Basic Functions done

This commit is contained in:
warlock
2022-02-27 16:46:13 +05:30
parent d4dd0864fa
commit 8c7ea9b86e
10 changed files with 421 additions and 160 deletions

View File

@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'main.dart';
import 'NewTask.dart';
import 'newActivity.dart';
import 'Data.dart';
import 'User.dart' as User;
import 'package:sn_progress_dialog/sn_progress_dialog.dart';
@@ -31,7 +32,7 @@ class _ActivitiesState extends State<Activities> {
floatingActionButton: FloatingActionButton.extended(
onPressed: () {
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => NewTask()))
.push(MaterialPageRoute(builder: (context) => NewActivity()))
.then((value) => UpdateList());
},
label: Text("New Activity"),
@@ -57,7 +58,7 @@ class _ActivitiesState extends State<Activities> {
]) : Container(),
],
)),
drawer: navDrawer(context, 3),
drawer: navDrawer(context, 2),
body: Container(
padding: EdgeInsets.all(10),
child: SingleChildScrollView(
@@ -67,41 +68,62 @@ class _ActivitiesState extends State<Activities> {
}
void UpdateList() async {
if(progressDialog != null){progressDialog.show(max:100,msg: 'Loading Task Types');}
await User.updateTasksList();
try{progressDialog.show(max:100,msg: 'Loading Activities');}catch(e){}
await User.updateActList();
setState(() {});
if(progressDialog != null){progressDialog.update(value: 100);}
try{progressDialog.update(value: 100);}catch(e){}
}
List<Widget> PrintTasks() {
List<Widget> _tasks = [];
print('Priting cats : ' + User.taskTypes.length.toString());
User.taskTypes.forEach((element) {
String name = element.name;
if (element.cat == null) {
print('Got some null cat : ${element.name}');
String lastDate = "";
DateFormat dFormat = DateFormat("MM/dd");
for (var element in User.activities) {
String thisDate = dFormat.format(element.startTime);
if(thisDate != lastDate){
_tasks.add(DateSeperator(thisDate));
lastDate=thisDate;
}
String name = element.taskType.name;
if (element.taskType.cat == null) {
print('Got some null cat : ${element.taskType.name}');
} else {
Color color = HexColor.fromHex(element.cat?.color ?? '#000000');
bool productive = element.cat?.productive ?? true;
Widget task = TaskCard(context, name, productive, color);
Color color = HexColor.fromHex(element.taskType.cat?.color ?? '#000000');
bool productive = element.taskType.cat?.productive ?? true;
Widget task = ActivityCard(context, name,element.startTime,element.endTime, productive, color,element);
_tasks.add(task);
}
});
}
return _tasks;
}
Widget DateSeperator(date){
return Padding(
padding: const EdgeInsets.fromLTRB(10, 20, 10, 0),
child: Column(children: [
Row(children: [
Text(date,style: TextStyle(fontSize: 18),)
],)
],),
);
}
bool selecting = false;
Widget TaskCard(
BuildContext context, String name, bool productive, Color color) {
Widget ActivityCard(
BuildContext context, String name,DateTime sTime, DateTime eTime, bool productive, Color color, Activity activity) {
DateFormat dateFormat = DateFormat("HH:mm");
var _timeSpan = eTime.difference(sTime);
String timeSpan = ((_timeSpan.inHours > 0) ? _timeSpan.inHours.toString()+'h ' : '') + ((_timeSpan.inMinutes %60 > 0) ? (_timeSpan.inMinutes%60).toString()+'m ' : '');
return Row(children: [
// Container(),
(selecting)
? Checkbox(
value: selectedTasks.contains(name),
value: selectedActivities.contains(activity),
onChanged: (value) {
print('selected $name');
OnItemSelected(name);
OnItemSelected(activity);
setState(() {});
})
: Container(),
@@ -116,7 +138,7 @@ class _ActivitiesState extends State<Activities> {
onTap: () {
//Open Respective Category
if(selecting){
OnItemSelected(name);
OnItemSelected(activity);
}
setState(() {
@@ -125,7 +147,7 @@ class _ActivitiesState extends State<Activities> {
onLongPress: () {
print('gonna delete');
selecting = !selecting;
selectedTasks = [name];
selectedActivities = [activity];
setState(() {});
},
@@ -137,8 +159,9 @@ class _ActivitiesState extends State<Activities> {
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(name,
Text(name + " ($timeSpan)",
style: TextStyle(color: Colors.white)),
Text(dateFormat.format(sTime) + " - " + dateFormat.format(eTime)),
// Icon(Icons.analytics, color: color, size: 20,),
Icon(Icons.circle,
color: (productive)
@@ -156,23 +179,24 @@ class _ActivitiesState extends State<Activities> {
]);
}
void OnItemSelected(String name){
if (!selectedTasks.contains(name)) {
selectedTasks.add(name);
void OnItemSelected(Activity activity){
if (!selectedActivities.contains(activity)) {
selectedActivities.add(activity);
} else {
selectedTasks.remove(name);
selectedActivities.remove(activity);
}
}
void DeleteSelectedTasks() async{
progressDialog.show(max: 100, msg: 'Deleteing ${selectedTasks.length} Task Types');
selectedTasks.forEach((element) async {
await User.UserOperations.deleteTask(element, bulk:true);
progressDialog.show(max: 100, msg: 'Deleteing ${selectedActivities.length} Task Types');
selectedActivities.forEach((element) async {
await User.UserOperations.deleteActivity(element, bulk:true);
});
await Future.delayed(Duration(seconds: 2));
await User.UserOperations.executeQueries();
selectedTasks=[];
await User.updateActList();
selectedActivities=[];
selecting=false;
setState(() {
progressDialog.update(value: 100);
@@ -182,4 +206,4 @@ class _ActivitiesState extends State<Activities> {
}
List<String> selectedTasks = [];
List<Activity> selectedActivities = [];

View File

@@ -77,6 +77,7 @@ class _NewTaskState extends State<NewTask> {
isExpanded: true,
items: getCategoryNames().map<DropdownMenuItem<String>>(
(String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),

View File

@@ -5,27 +5,26 @@ import 'Data.dart';
import 'User.dart' as User;
import 'package:sn_progress_dialog/sn_progress_dialog.dart';
late ProgressDialog progressDialog;
class Tasks extends StatefulWidget {
const Tasks({Key? key}) : super(key: key);
@override
_TasksState createState() => _TasksState();
}
late ProgressDialog progressDialog;
class _TasksState extends State<Tasks> {
@override
void initState() {
// TODO: implement initState
super.initState();
progressDialog = ProgressDialog(context: context);
User.progressDialog=progressDialog;
UpdateList();
}
@override
Widget build(BuildContext context) {
progressDialog=ProgressDialog(context: context);
return Scaffold(
floatingActionButton: FloatingActionButton.extended(
@@ -67,10 +66,13 @@ class _TasksState extends State<Tasks> {
}
void UpdateList() async {
if(progressDialog != null){progressDialog.show(max:100,msg: 'Loading Task Types');}
try{progressDialog.show(max:100, msg: 'Loading Task Types...');}catch(e){}
await User.updateTasksList();
// hideProgressDialog();
setState(() {});
if(progressDialog != null){progressDialog.update(value: 100);}
try{progressDialog.update(value: 100);}catch(e){}
}
List<Widget> PrintTasks() {
@@ -165,7 +167,7 @@ class _TasksState extends State<Tasks> {
}
void DeleteSelectedTasks() async{
progressDialog.show(max: 100, msg: 'Deleteing ${selectedTasks.length} Task Types');
progressDialog.show(max: 100, msg: "Deleting ${selectedTasks.length} ");
selectedTasks.forEach((element) async {
await User.UserOperations.deleteTask(element, bulk:true);
});

View File

@@ -1,6 +1,10 @@
import 'dart:async';
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'main.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'Data.dart';
@@ -8,7 +12,8 @@ import 'package:sqflite/sqflite.dart';
import 'package:path_provider/path_provider.dart';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:sn_progress_dialog/sn_progress_dialog.dart';
import 'Tasks.dart';
late ProgressDialog? progressDialog;
late http.Response loginResponse;
late Database cacheDb;
@@ -17,8 +22,10 @@ List<Category> categories = [];
List<TaskType> taskTypes = [];
List<Activity> activities=[];
bool offline = true;
bool registered = false;
Future<http.Response> login(String _username, String password) async {
final prefs = await SharedPreferences.getInstance();
username = _username;
var device_id = await Settings.UUID();
try {
@@ -27,12 +34,18 @@ Future<http.Response> login(String _username, String password) async {
body: <String, String>{
"username": _username,
"password": password,
"device_id": device_id ?? 'n/a'
"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){
offline=true;
@@ -42,35 +55,50 @@ Future<http.Response> login(String _username, String password) async {
Future<void> initUserData() async {
await initCacheDatabase();
await UpdateCategoriesFromServer();
await UpdateTaskTypesFromServer();
await GetCategories(true);
await GetTaskTypes(true);
await refreshUserData();
print('Initializing UserData...');
if (offline) {
print('Going offline mode.');
}
}
Future<void> refreshUserData() async{
ShowProgress("Loading data");
// categories= await GetCategories(true);
// taskTypes= await GetTaskTypes(true);
// activities= await GetActivities(true);
await updateCatsList();
await updateTasksList();
await updateActList();
HideProgress();
}
Future<bool> cacheDbExist() async{
Directory directory = await getApplicationDocumentsDirectory();
return databaseFactory.databaseExists(directory.path + 'cache.db');
}
Future<void> updateCatsList() async{
print('Updating with localCache');
categories = await GetCategories(true);
//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('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();
@@ -102,13 +130,18 @@ void onCacheDatabaseCreate(Database db, int newVersion) async {
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();
addInitialDataToCache();
if(prefs.getBool("registered") ?? false) {
addInitialDataToCache();
prefs.setBool("registered", false);
}
// GetCategories();
}
Future<void> addInitialDataToCache() async{
ShowProgress("Initializing User Data");
print("adding init data");
await Future.delayed(const Duration(seconds: 1));
//Insert Initial Entries
@@ -124,9 +157,9 @@ Future<void> addInitialDataToCache() async{
// };
// await cacheDb.insert('TaskTypes', data);
}
UserOperations.executeQueries();
HideProgress();
await UserOperations.executeQueries();
await refreshUserData();
}
void onCacheDatabaseUpgrade(Database db, int oldVersion, int newVersion) async {
@@ -150,7 +183,7 @@ Future<List<Category>> GetCategories(bool forceOffline) async{
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??'n/a'}));
body: <String, String>{"username": username, "device_id":android_id}));
final data = update_response.body.split(',');
catsUpdated = data[0] == '1';
}catch(e){
@@ -160,9 +193,9 @@ Future<List<Category>> GetCategories(bool forceOffline) async{
print("Need to update : ${!catsUpdated}");
//Update CacheDB
if(!catsUpdated){
//if(!catsUpdated){
await UpdateCategoriesFromServer();
}
// }
}
List<Map> cats = await cacheDb.query('Categories');
@@ -184,25 +217,27 @@ Future<List<Category>> GetCategories(bool forceOffline) async{
}
Future<void> UpdateCategoriesFromServer() async{
print("Updating Categories");
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() ?? 'n/a'
"device_id": await Settings.UUID()
}));
print(response.body);
List<String> data = response.body.split("<td>");
data.forEach((value) async {
// 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){
offline=true;
}
@@ -222,7 +257,7 @@ Future<List<TaskType>> GetTaskTypes(bool forceOffline) async{
//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??'n/a'}));
body: <String, String>{"username": username, "device_id":android_id}));
final data = update_response.body.split(',');
updated = data[1] == '1';
}catch(e){
@@ -232,11 +267,13 @@ Future<List<TaskType>> GetTaskTypes(bool forceOffline) async{
print("Need to update : ${!updated}");
//Update CacheDB
if(!updated){
// 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){
@@ -257,31 +294,37 @@ Future<List<TaskType>> GetTaskTypes(bool forceOffline) async{
}
Future<void> UpdateTaskTypesFromServer() async{
print("Updating TaskTypes");
// 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() ?? 'n/a'
"device_id": await Settings.UUID()
}));
print(response.body);
List<String> data = response.body.split("<td>");
data.forEach((value) async {
await cacheDb.delete("TaskTypes");
for (var value in data) {
Map<String, dynamic> cat = jsonDecode(value);
//print(catData);
print(cat);
await cacheDb.rawInsert(
"INSERT OR REPLACE INTO TaskTypes (${TaskType.colId},${TaskType
.colName},${TaskType.colCategory}) "
"VALUES ('${cat['id']}','${cat['name']}',${cat['category']}) ");
});
"VALUES ('${cat['task_id']}','${cat['name']}','${cat['category_id']}') ");
print(await cacheDb.query("TaskTypes"));
}
}catch(e){
offline=true;
}
}
Future<List<TaskType>> GetActivities(bool forceOffline) async{
Future<List<Activity>> GetActivities(bool forceOffline) async{
List<Activity> _activities = [];
if(offline || forceOffline){
//Retreive from cacheDB
@@ -295,7 +338,7 @@ Future<List<TaskType>> GetActivities(bool forceOffline) async{
//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??'n/a'}));
body: <String, String>{"username": username, "device_id":android_id}));
final data = update_response.body.split(',');
updated = data[2] == '1';
}catch(e){
@@ -305,17 +348,17 @@ Future<List<TaskType>> GetActivities(bool forceOffline) async{
print("Need to update activities : ${!updated}");
//Update CacheDB
if(!updated){
//if(!updated){
await UpdateActivitiesFromServer();
}
//}
}
List<Map> cats = await cacheDb.query('Activities');
List<Map> cats = await cacheDb.rawQuery('SELECT * FROM Activities ORDER BY ${Activity.colStartTime} DESC');
print(cats.length);
for(Map element in cats){
String? type = element[Activity.colType].toString();
String? startTime = element[Activity.colStartTime].toString();
String? endTime = element[Activity.colStartTime].toString();
String? endTime = element[Activity.colEndTime].toString();
TaskType? taskType = await getTaskFromId(type);
if(type==null || startTime==null || endTime==null || taskType==null){
print("Something is null!");
@@ -326,29 +369,40 @@ Future<List<TaskType>> GetActivities(bool forceOffline) async{
_activities.add(Activity(taskType, DateTime.parse(startTime), DateTime.parse(endTime)));
}
activities = _activities;
return taskTypes;
return activities;
}
Future<void> UpdateActivitiesFromServer() async{
print("Updating TaskTypes");
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() ?? 'n/a'
"device_id": await Settings.UUID()
}));
print(response.body);
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>");
data.forEach((value) async {
for (var value in data){
Map<String, dynamic> cat = jsonDecode(value);
//print(catData);
print(cat);
await cacheDb.rawInsert(
"INSERT OR REPLACE INTO Activities (${Activity.colType}, ${Activity.colStartTime}, ${Activity.colEndTime}) "
"VALUES ('${cat['type']}', '${cat['sTime']}','${cat['eTime']}') ");
});
"VALUES ('${cat['task_id']}', '${cat['sTime']}','${cat['eTime']}') ");
}
}else{
print("No activities for now");
}
}catch(e){
print("Error : $e @ updating activities");
offline=true;
}
}
@@ -402,7 +456,7 @@ class UserOperations{
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() ?? 'n/a',
'device_id': await Settings.UUID(),
'name' : name,
'color':color,
'productive': productive ? '1':'0'
@@ -437,7 +491,7 @@ class UserOperations{
Map<String,String> queryBody= <String,String>{
'id':username+name,
'username': username,
'device_id': await Settings.UUID() ?? 'n/a',
'device_id': await Settings.UUID(),
'name' : name,
'category': username + category
};
@@ -465,11 +519,51 @@ class UserOperations{
}
}
static Future<void> addActivity(String type, String sTime,String eTime, {bool bulk = false, Function(int)? onOverlap}) async{
//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);
}
Map<String,String> queryBody= <String,String>{
'username': username,
'device_id': await Settings.UUID(),
'type' : username+type,
'sTime': sTime,
'eTime':eTime
};
//Add Query
Map<String,Object> query = {
Queries.colLink: 'add_activity',
Queries.colData: jsonEncode(queryBody)
};
print("adding new query ${query[Queries.colLink]} : ${jsonEncode(queryBody)}");
await cacheDb.insert('Queries', query);
//update Cache
Map<String,Object> data = {
Activity.colType: type,
Activity.colStartTime: sTime,
Activity.colEndTime: eTime
};
await cacheDb.insert('Activities', data);
await GetActivities(true);
if(!bulk){
//Add to server and refresh Cache
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() ?? 'n/a',
'device_id': await Settings.UUID(),
};
//Add Query
Map<String,Object> query = {
@@ -499,7 +593,7 @@ class UserOperations{
Map<String,String> queryBody= <String,String>{
'id':username+name,
'username': username,
'device_id': await Settings.UUID() ?? 'n/a',
'device_id': await Settings.UUID() ,
};
//Add Query
Map<String,Object> query = {
@@ -525,13 +619,43 @@ class UserOperations{
}
}
static Future<void> deleteActivity(Activity activity,{bulk=false}) async{
Map<String,String> queryBody= <String,String>{
'username': username,
'device_id': await Settings.UUID(),
'sTime': activity.startTime.toString(),
'eTime':activity.endTime.toString(),
};
//Add Query
Map<String,Object> query = {
Queries.colLink: 'delete_activity',
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,
// };
// await cacheDb.rawDelete("DELETE FROM Categories WHERE ${Category.colCatId}='${username+name}'");
await GetCategories(true);
//Add to server and refresh Cache
if(!bulk) {
await executeQueries();
}
}
static Future<void> executeQueries() async{
if(offline){
print("Cannot executre queries, Offline!");
return;
}
ShowProgress("Syncing");
List<Map<String,Object?>> queries = await cacheDb.query('Queries');
for(Map<String,Object?> element in queries){
@@ -559,6 +683,15 @@ class UserOperations{
offline=true;
}
}
HideProgress();
}
}
void ShowProgress(msg){
try{progressDialog?.show(max: 100, msg: msg);}catch(e){}
}
void HideProgress(){
try{progressDialog?.update(value: 100);}catch(e){}
}

View File

@@ -18,7 +18,8 @@ class _WelcomePageState extends State<WelcomePage> {
child: Scaffold(
body: Container(
color: Colors.pink,
child: Column(
child: Flex(
direction: Axis.vertical,
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
@@ -30,13 +31,11 @@ class _WelcomePageState extends State<WelcomePage> {
// style: TextStyle(fontSize: 40, fontWeight: FontWeight.bold),
// textAlign: TextAlign.left,
// )),
Container(
height: 300,
padding: EdgeInsets.fromLTRB(0, 100, 0, 0),
child: Expanded(
Expanded(
child: Container(
padding: EdgeInsets.symmetric(horizontal: 100, vertical: 10),
child: Image(image: AssetImage('images/Launch.png')))),
),
Container(
padding: EdgeInsets.all(20),
child: Column(
@@ -90,30 +89,37 @@ class _SignInPageState extends State<SignInPage> {
child: Scaffold(
body: Container(
color: Colors.deepPurpleAccent,
child: Column(
child: Flex(
direction: Axis.vertical,
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(padding: EdgeInsets.fromLTRB(0, 100, 0, 0),
height: 400,
child: Expanded(
Expanded(
flex: 2,
child: Container(
padding: EdgeInsets.fromLTRB(0, 100, 0, 0),
height: 400,
child:
Image(image: AssetImage('images/signin.png'))),
)),
Container(
padding: EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Sign in to stay connected",
style: TextStyle(
fontSize: 30,
fontWeight: FontWeight.bold)),
Divider(),
Text(
"Sign in and enjoy the flawless connection between all your devices. You can track your day from any device and keep it together.")
],
),
Expanded(
flex:1,
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Sign in to stay connected",
style: TextStyle(
fontSize: 30,
fontWeight: FontWeight.bold)),
Divider(),
Text(
"Sign in and enjoy the flawless connection between all your devices. You can track your day from any device and keep it together.")
],
),
)),
Container(
padding: EdgeInsets.all(20),
@@ -173,7 +179,8 @@ class _onlineLoginPageState extends State<onlineLoginPage>
child: Scaffold(
body: Container(
color: Colors.purpleAccent,
child: Column(
child: Flex(
direction: Axis.vertical,
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
@@ -187,12 +194,12 @@ class _onlineLoginPageState extends State<onlineLoginPage>
// textAlign: TextAlign.left,
// ),
// ),
Container(
child: Expanded(
Expanded(
child: Container(
child:
Image(image: AssetImage('images/signin.png'))),
)),
),
Container(
padding: EdgeInsets.all(20),
child: Column(children: [
@@ -240,11 +247,9 @@ class _onlineLoginPageState extends State<onlineLoginPage>
style:
TextStyle(fontSize: 16),
)),
Container(
height: 70,
padding: EdgeInsets.all(10),
child: Expanded(
Expanded(
child: Container(
padding: EdgeInsets.all(15),
child: TextField(
controller: usernameController,
autocorrect: false,
@@ -263,7 +268,7 @@ class _onlineLoginPageState extends State<onlineLoginPage>
10))),
),
),
)),
),
Container(
alignment: Alignment.centerLeft,
padding: EdgeInsets.fromLTRB(
@@ -273,11 +278,9 @@ class _onlineLoginPageState extends State<onlineLoginPage>
style:
TextStyle(fontSize: 16),
)),
Container(
height: 70,
padding: EdgeInsets.all(10),
child: Expanded(
Expanded(
child: Container(
padding: EdgeInsets.all(15),
child: TextField(
controller: passwordController,
obscureText: true,
@@ -300,7 +303,7 @@ class _onlineLoginPageState extends State<onlineLoginPage>
10))),
),
),
)),
),
Container(
width: 200,
padding: EdgeInsets.all(20),
@@ -435,7 +438,8 @@ class _offlineLoginPageState extends State<offlineLoginPage> {
child: Scaffold(
body: Container(
color: Colors.deepOrange,
child: Column(
child: Flex(
direction: Axis.vertical,
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
@@ -447,13 +451,11 @@ class _offlineLoginPageState extends State<offlineLoginPage> {
// style: TextStyle(fontSize: 40, fontWeight: FontWeight.bold),
// textAlign: TextAlign.left,
// )),
Container(
// padding: EdgeInsets.all(50),
child: Expanded(
Expanded(
child: Container(
height: 400,
child: Image(
image: AssetImage('images/offline.png')))),
image: AssetImage('images/offline.png'))),
),
Container(
padding: EdgeInsets.all(20),

View File

@@ -8,8 +8,37 @@ import 'package:charts_flutter/flutter.dart' as charts;
import 'NewTask.dart';
import 'newActivity.dart';
import 'Tasks.dart';
import 'Activities.dart';
import 'User.dart' as User;
import 'package:sn_progress_dialog/sn_progress_dialog.dart';
late ProgressDialog progressDialog;
showAlertDialog(BuildContext context, String title, String message) {
// set up the button
Widget okButton = TextButton(
child: Text("OK"),
onPressed: () { Navigator.of(context).pop(); },
);
// set up the AlertDialog
AlertDialog alert = AlertDialog(
title: Text(title),
content: Text(message),
actions: [
okButton,
],
);
// show the dialog
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
}
extension HexColor on Color {
/// String is in the format "aabbcc" or "ffaabbcc" with an optional leading "#".
@@ -49,7 +78,7 @@ final List<PopulationData> data = [
];
void main() {
Wakelock.enable(); // or Wakelock.toggle(on: true);
//Wakelock.enable(); // or Wakelock.toggle(on: true);
runApp(const MyApp());
}
@@ -72,7 +101,8 @@ class MyApp extends StatelessWidget {
'/welcome':(context)=> const WelcomePage(),
'/':(context) => const MyHomePage(),
'/Tasks':(context)=> const Tasks(),
'/Categories':(context)=>const Categories()
'/Categories':(context)=>const Categories(),
'/Activities':(context)=>const Activities()
}
);
}
@@ -101,6 +131,8 @@ class _MyHomePageState extends State<MyHomePage> {
super.initState();
showOfflineSnack();
progressDialog = ProgressDialog(context: context);
User.progressDialog=progressDialog;
}
void showOfflineSnack() async{

View File

@@ -12,17 +12,23 @@ class NewActivity extends StatefulWidget {
_NewActivity createState() => _NewActivity();
}
List<String> getActivitiesNames(){
String selectedCat = User.taskTypes[0].name;
List<String> getActivities(){
List<String> _cats = [];
User.activities.forEach((element) {
String name = element.taskType.name;
_cats.add(name);
print(User.taskTypes[0].name + " : " + selectedCat);
User.taskTypes.forEach((element) {
String name = element.name;
if(_cats.contains(element.name)){
}else{
_cats.add(name);}
});
return _cats;
}
class _NewActivity extends State<NewActivity> {
String value = 'CS:GO';
DateTime startTime = DateTime.now();
DateTime endTime = DateTime.now().add(Duration(minutes: 30));
@override
@@ -57,24 +63,19 @@ class _NewActivity extends State<NewActivity> {
iconSize: 30,
elevation: 10,
borderRadius: BorderRadius.circular(10),
value: value,
value: selectedCat,
isExpanded: true,
items: <String>[
'Rocket League',
'CS:GO',
'HALO',
'Unity',
'Add new Task Type...'
].map<DropdownMenuItem<String>>(
(String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
items: getActivities().map<DropdownMenuItem<String>>(
(String value) {
print(value);
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
onChanged: (String? _value) {
setState(() {
value = _value!;
selectedCat = _value ?? 'n/a';
});
})),
Container(
@@ -101,7 +102,14 @@ class _NewActivity extends State<NewActivity> {
// print('change $date');
}, onConfirm: (date) {
setState(() {
startTime = date;
if(endTime.compareTo(date) < 0){
const snackBar = SnackBar(
content: Text('You cannot start something after you ended it!'),
);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}else {
startTime = date;
}
});
},
currentTime: startTime,
@@ -136,7 +144,14 @@ class _NewActivity extends State<NewActivity> {
// print('change $date');
}, onConfirm: (date) {
setState(() {
endTime = date;
if(startTime.compareTo(date) > 0){
const snackBar = SnackBar(
content: Text('You cannot end something before you start it!'),
);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}else {
endTime = date;
}
});
},
currentTime: endTime,
@@ -151,7 +166,10 @@ class _NewActivity extends State<NewActivity> {
),
Text('Duration : ' +
_printDuration(
endTime.difference(startTime))),
endTime.difference(startTime)),
style:TextStyle(
fontSize: 20,
)),
Divider(
height: 30,
),
@@ -192,7 +210,12 @@ class _NewActivity extends State<NewActivity> {
shape: StadiumBorder()
),
onPressed: () {
setState(() {});
add_action();
setState(() {
});
},
child: Text('Add Entry',
style: TextStyle(fontSize: 20))))),
@@ -200,6 +223,20 @@ class _NewActivity extends State<NewActivity> {
))
])));
}
void add_action() async{
print('adding Task Type : $selectedCat at $startTime - $endTime');
bool failed=false;
await User.UserOperations.addActivity(selectedCat,startTime.toString(), endTime.toString(), onOverlap: (overlapCount){
showAlertDialog(context, 'Error adding activity', 'Cannot add activity between ${dateFormat.format(startTime)} - ${dateFormat.format(endTime)}, $overlapCount activities are already added within this time range');
failed=true;
});
if(!failed)
Navigator.of(context).pop();
}
}
String _printDuration(Duration duration) {
@@ -208,3 +245,29 @@ String _printDuration(Duration duration) {
String twoDigitSeconds = twoDigits(duration.inSeconds.remainder(60));
return "${twoDigits(duration.inHours)}:$twoDigitMinutes:$twoDigitSeconds";
}
showAlertDialog(BuildContext context, String title, String message) {
// set up the button
Widget okButton = TextButton(
child: Text("OK"),
onPressed: () { Navigator.of(context).pop(); },
);
// set up the AlertDialog
AlertDialog alert = AlertDialog(
title: Text(title),
content: Text(message),
actions: [
okButton,
],
);
// show the dialog
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
}

View File

@@ -2,7 +2,9 @@ import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'User.dart' as Users;
import 'package:http/http.dart' as http;
import 'package:sn_progress_dialog/sn_progress_dialog.dart';
late ProgressDialog progressDialog;
class SplashScreen extends StatefulWidget {
const SplashScreen({Key? key}) : super(key: key);
@@ -15,6 +17,8 @@ class _SplashScreenState extends State<SplashScreen> {
void initState() {
// TODO: implement initState
super.initState();
progressDialog = ProgressDialog(context: context);
Users.progressDialog=progressDialog;
init();
}