Todo basics added
This commit is contained in:
@@ -8,6 +8,7 @@ import 'newActivity.dart';
|
|||||||
import 'Data.dart';
|
import 'Data.dart';
|
||||||
import 'User.dart' as User;
|
import 'User.dart' as User;
|
||||||
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
|
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
|
||||||
|
|
||||||
class Activities extends StatefulWidget {
|
class Activities extends StatefulWidget {
|
||||||
const Activities({Key? key}) : super(key: key);
|
const Activities({Key? key}) : super(key: key);
|
||||||
|
|
||||||
@@ -15,8 +16,6 @@ class Activities extends StatefulWidget {
|
|||||||
_ActivitiesState createState() => _ActivitiesState();
|
_ActivitiesState createState() => _ActivitiesState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class _ActivitiesState extends State<Activities> {
|
class _ActivitiesState extends State<Activities> {
|
||||||
//late ProgressDialog progressDialog;
|
//late ProgressDialog progressDialog;
|
||||||
TextEditingController searchController = TextEditingController();
|
TextEditingController searchController = TextEditingController();
|
||||||
@@ -28,11 +27,10 @@ class _ActivitiesState extends State<Activities> {
|
|||||||
|
|
||||||
if (!_focus.hasFocus) {
|
if (!_focus.hasFocus) {
|
||||||
searching = false;
|
searching = false;
|
||||||
setState(() {
|
setState(() {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var refreshSub;
|
var refreshSub;
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@@ -41,9 +39,7 @@ class _ActivitiesState extends State<Activities> {
|
|||||||
_focus.addListener(_onFocusChange);
|
_focus.addListener(_onFocusChange);
|
||||||
refreshSub = User.refreshStream.stream.listen((event) {
|
refreshSub = User.refreshStream.stream.listen((event) {
|
||||||
if (!event) {
|
if (!event) {
|
||||||
setState(() {
|
setState(() {});
|
||||||
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
//UpdateList();
|
//UpdateList();
|
||||||
@@ -58,6 +54,7 @@ class _ActivitiesState extends State<Activities> {
|
|||||||
_focus.dispose();
|
_focus.dispose();
|
||||||
refreshSub?.closeStream();
|
refreshSub?.closeStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateList() async {
|
void UpdateList() async {
|
||||||
try {
|
try {
|
||||||
//progressDialog.show(max: 100, msg: 'Loading Activities');
|
//progressDialog.show(max: 100, msg: 'Loading Activities');
|
||||||
@@ -68,6 +65,7 @@ class _ActivitiesState extends State<Activities> {
|
|||||||
// progressDialog.update(value: 100);
|
// progressDialog.update(value: 100);
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, ActivityListDateGroup> activitiesGroups = <String, ActivityListDateGroup>{};
|
Map<String, ActivityListDateGroup> activitiesGroups = <String, ActivityListDateGroup>{};
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@@ -91,18 +89,23 @@ class _ActivitiesState extends State<Activities> {
|
|||||||
mainAxisSize: MainAxisSize.max,
|
mainAxisSize: MainAxisSize.max,
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: TextField(onChanged: (text){setState(() {
|
child: TextField(
|
||||||
|
onChanged: (text) {
|
||||||
});},controller: searchController, focusNode: _focus, decoration: InputDecoration(
|
setState(() {});
|
||||||
|
},
|
||||||
|
controller: searchController,
|
||||||
|
focusNode: _focus,
|
||||||
|
decoration: InputDecoration(
|
||||||
filled: true,
|
filled: true,
|
||||||
),),
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
InkWell(
|
InkWell(
|
||||||
onTap: (){searching=false;
|
onTap: () {
|
||||||
|
searching = false;
|
||||||
searchController.clear();
|
searchController.clear();
|
||||||
setState(() {
|
setState(() {});
|
||||||
|
},
|
||||||
});},
|
|
||||||
child: Container(
|
child: Container(
|
||||||
margin: EdgeInsets.all(10),
|
margin: EdgeInsets.all(10),
|
||||||
child: Icon(Icons.cancel),
|
child: Icon(Icons.cancel),
|
||||||
@@ -110,7 +113,10 @@ class _ActivitiesState extends State<Activities> {
|
|||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
Text('searched time : ${Main.MinutesToTimeString(searchTime)}',style: TextStyle(fontSize: 15),)
|
Text(
|
||||||
|
'searched time : ${Main.MinutesToTimeString(searchTime)}',
|
||||||
|
style: TextStyle(fontSize: 15),
|
||||||
|
)
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
: Row(
|
: Row(
|
||||||
@@ -131,7 +137,6 @@ class _ActivitiesState extends State<Activities> {
|
|||||||
size: 30,
|
size: 30,
|
||||||
),
|
),
|
||||||
)),
|
)),
|
||||||
|
|
||||||
InkWell(
|
InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
@@ -147,9 +152,7 @@ class _ActivitiesState extends State<Activities> {
|
|||||||
onTap: () {
|
onTap: () {
|
||||||
searching = true;
|
searching = true;
|
||||||
_focus.requestFocus();
|
_focus.requestFocus();
|
||||||
setState(() {
|
setState(() {});
|
||||||
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
margin: EdgeInsets.all(10),
|
margin: EdgeInsets.all(10),
|
||||||
@@ -161,9 +164,7 @@ class _ActivitiesState extends State<Activities> {
|
|||||||
InkWell(
|
InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
UpdateList();
|
UpdateList();
|
||||||
setState(() {
|
setState(() {});
|
||||||
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
child: Container(margin: EdgeInsets.all(10), child: Icon(Icons.refresh, size: 30)),
|
child: Container(margin: EdgeInsets.all(10), child: Icon(Icons.refresh, size: 30)),
|
||||||
)
|
)
|
||||||
@@ -180,11 +181,10 @@ class _ActivitiesState extends State<Activities> {
|
|||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
// return activities[index];
|
// return activities[index];
|
||||||
return StickyHeader(
|
return StickyHeader(
|
||||||
|
|
||||||
header: activitiesGroups.values.toList()[index].dateSeperator,
|
header: activitiesGroups.values.toList()[index].dateSeperator,
|
||||||
content:Column(children: activitiesGroups.values.toList()[index].activities,)
|
content: Column(
|
||||||
);
|
children: activitiesGroups.values.toList()[index].activities,
|
||||||
|
));
|
||||||
})
|
})
|
||||||
// SingleChildScrollView(
|
// SingleChildScrollView(
|
||||||
// child: Column(
|
// child: Column(
|
||||||
@@ -192,12 +192,12 @@ class _ActivitiesState extends State<Activities> {
|
|||||||
// ))
|
// ))
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
DateFormat dFormat = DateFormat("yyyy-MM-dd");
|
DateFormat dFormat = DateFormat("yyyy-MM-dd");
|
||||||
ItemScrollController scrollController = ItemScrollController();
|
ItemScrollController scrollController = ItemScrollController();
|
||||||
ScrollController controller = ScrollController();
|
ScrollController controller = ScrollController();
|
||||||
int searchTime = 0;
|
int searchTime = 0;
|
||||||
Map<String, ActivityListDateGroup> PrintTasks() {
|
Map<String, ActivityListDateGroup> PrintTasks() {
|
||||||
|
|
||||||
Map<String, ActivityListDateGroup> _tasks = <String, ActivityListDateGroup>{};
|
Map<String, ActivityListDateGroup> _tasks = <String, ActivityListDateGroup>{};
|
||||||
|
|
||||||
print('Priting cats : ' + User.taskTypes.length.toString());
|
print('Priting cats : ' + User.taskTypes.length.toString());
|
||||||
@@ -250,7 +250,6 @@ class _ActivitiesState extends State<Activities> {
|
|||||||
|
|
||||||
String thisDate = dFormat.format(element.startTime);
|
String thisDate = dFormat.format(element.startTime);
|
||||||
|
|
||||||
|
|
||||||
if (thisDate != lastDate) {
|
if (thisDate != lastDate) {
|
||||||
int prodActs = productivtyActs[thisDate] ?? 0;
|
int prodActs = productivtyActs[thisDate] ?? 0;
|
||||||
int unProdActs = unproductivtyActs[thisDate] ?? 0;
|
int unProdActs = unproductivtyActs[thisDate] ?? 0;
|
||||||
@@ -291,18 +290,20 @@ class _ActivitiesState extends State<Activities> {
|
|||||||
String gap = Main.MinutesToTimeString(sTime.difference(eTime).inMinutes);
|
String gap = Main.MinutesToTimeString(sTime.difference(eTime).inMinutes);
|
||||||
return Row(
|
return Row(
|
||||||
mainAxisSize: MainAxisSize.max,
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
|
||||||
children: [
|
|
||||||
Container(padding: EdgeInsets.fromLTRB(10, 0, 5, 0), child: Column(
|
|
||||||
mainAxisSize: MainAxisSize.max,mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: [
|
children: [
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.fromLTRB(10, 0, 5, 0),
|
||||||
|
child: Column(mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.center, children: [
|
||||||
// Text(dateFormat.format(activity.endTime)),
|
// Text(dateFormat.format(activity.endTime)),
|
||||||
SizedBox(width: 1, height: 30, child: Container(color: Colors.white)),
|
SizedBox(width: 1, height: 30, child: Container(color: Colors.white)),
|
||||||
Text(dateFormat.format(eTime))])),
|
Text(dateFormat.format(eTime))
|
||||||
|
])),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Navigator.of(context).push(MaterialPageRoute(builder: (context) => NewActivity(sTime: eTime,eTime: sTime))).then((value) => UpdateList());
|
Navigator.of(context)
|
||||||
|
.push(MaterialPageRoute(builder: (context) => NewActivity(sTime: eTime, eTime: sTime)))
|
||||||
|
.then((value) => UpdateList());
|
||||||
},
|
},
|
||||||
child: Card(
|
child: Card(
|
||||||
child: Row(
|
child: Row(
|
||||||
@@ -315,15 +316,10 @@ class _ActivitiesState extends State<Activities> {
|
|||||||
child: Text('Untracked period $gap'),
|
child: Text('Untracked period $gap'),
|
||||||
),
|
),
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [Icon(Icons.add, size: 30), Text("Add Activity")],
|
||||||
Icon(Icons.add,size:30),
|
|
||||||
Text("Add Activity")
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
|
|
||||||
],
|
],
|
||||||
)
|
)),
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -335,7 +331,6 @@ class _ActivitiesState extends State<Activities> {
|
|||||||
List<String> keys = activitiesGroups.keys.toList();
|
List<String> keys = activitiesGroups.keys.toList();
|
||||||
List<ActivityListDateGroup> values = activitiesGroups.values.toList();
|
List<ActivityListDateGroup> values = activitiesGroups.values.toList();
|
||||||
for (int i = 0; i < activitiesGroups.length; i++) {
|
for (int i = 0; i < activitiesGroups.length; i++) {
|
||||||
|
|
||||||
if (keys[i] == dFormat.format(date)) {
|
if (keys[i] == dFormat.format(date)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -374,7 +369,9 @@ class _ActivitiesState extends State<Activities> {
|
|||||||
},
|
},
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
SizedBox(width: 15,),
|
SizedBox(
|
||||||
|
width: 15,
|
||||||
|
),
|
||||||
Icon(Icons.circle),
|
Icon(Icons.circle),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: 10,
|
width: 10,
|
||||||
@@ -390,10 +387,18 @@ class _ActivitiesState extends State<Activities> {
|
|||||||
children: [
|
children: [
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
if(prodPercentage < 35)Text(Main.MinutesToTimeString(prodActs),),
|
if (prodPercentage < 35)
|
||||||
|
Text(
|
||||||
|
Main.MinutesToTimeString(prodActs),
|
||||||
|
),
|
||||||
Container(
|
Container(
|
||||||
child: Align(
|
child: Align(
|
||||||
child: (prodPercentage >= 35) ?FittedBox(child: Text(Main.MinutesToTimeString(prodActs),)) : Container(),
|
child: (prodPercentage >= 35)
|
||||||
|
? FittedBox(
|
||||||
|
child: Text(
|
||||||
|
Main.MinutesToTimeString(prodActs),
|
||||||
|
))
|
||||||
|
: Container(),
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
),
|
),
|
||||||
width: (prodPercentage) * 1,
|
width: (prodPercentage) * 1,
|
||||||
@@ -415,7 +420,8 @@ class _ActivitiesState extends State<Activities> {
|
|||||||
SizedBox(
|
SizedBox(
|
||||||
width: 10,
|
width: 10,
|
||||||
),
|
),
|
||||||
Text(prodPercentage.toStringAsFixed(1) + "%", style: TextStyle(color: Colors.green, fontWeight: FontWeight.bold, fontSize: 20))
|
Text(prodPercentage.toStringAsFixed(1) + "%",
|
||||||
|
style: TextStyle(color: Colors.green, fontWeight: FontWeight.bold, fontSize: 20))
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
// CustomPaint(
|
// CustomPaint(
|
||||||
@@ -436,20 +442,22 @@ class _ActivitiesState extends State<Activities> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool selecting = false;
|
bool selecting = false;
|
||||||
Widget ActivityCard(BuildContext context, String name, DateTime sTime, DateTime eTime, bool productive, Color color, Activity activity, int totalMinutes) {
|
Widget ActivityCard(
|
||||||
|
BuildContext context, String name, DateTime sTime, DateTime eTime, bool productive, Color color, Activity activity, int totalMinutes) {
|
||||||
DateFormat dateFormat = DateFormat("HH:mm");
|
DateFormat dateFormat = DateFormat("HH:mm");
|
||||||
int thisMinutes = (activity.endTime.difference(activity.startTime).inMinutes);
|
int thisMinutes = (activity.endTime.difference(activity.startTime).inMinutes);
|
||||||
|
|
||||||
int timePercentage = ((thisMinutes / totalMinutes) * 100).toInt();
|
int timePercentage = ((thisMinutes / totalMinutes) * 100).toInt();
|
||||||
// print("$thisMinutes / $totalMinutes");
|
// print("$thisMinutes / $totalMinutes");
|
||||||
bool containsMetadata = ((activity.metadata ?? 'null') != 'null') && ((activity.metadata ?? '').isNotEmpty);
|
bool containsMetadata = ((activity.metadata ?? 'null') != 'null') && ((activity.metadata ?? '').isNotEmpty);
|
||||||
|
bool containsStepData = (containsMetadata && activity.metadata!.contains('[') && activity.metadata!.contains(']'));
|
||||||
var _timeSpan = eTime.difference(sTime);
|
var _timeSpan = eTime.difference(sTime);
|
||||||
String timeSpan = ((_timeSpan.inHours > 0) ? _timeSpan.inHours.toString() + 'h ' : '') + ((_timeSpan.inMinutes % 60 > 0) ? (_timeSpan.inMinutes % 60).toString() + 'm' : '');
|
String timeSpan = ((_timeSpan.inHours > 0) ? _timeSpan.inHours.toString() + 'h ' : '') +
|
||||||
|
((_timeSpan.inMinutes % 60 > 0) ? (_timeSpan.inMinutes % 60).toString() + 'm' : '');
|
||||||
return Row(children: [
|
return Row(children: [
|
||||||
// Container(),
|
// Container(),
|
||||||
(selecting)
|
(selecting)
|
||||||
@@ -460,8 +468,11 @@ class _ActivitiesState extends State<Activities> {
|
|||||||
OnItemSelected(activity);
|
OnItemSelected(activity);
|
||||||
setState(() {});
|
setState(() {});
|
||||||
})
|
})
|
||||||
: Container(padding: EdgeInsets.fromLTRB(10, 0, 5, 0), child: Column(
|
: Container(
|
||||||
mainAxisSize: MainAxisSize.max,mainAxisAlignment: MainAxisAlignment.center,
|
padding: EdgeInsets.fromLTRB(10, 0, 5, 0),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
// Text(dateFormat.format(activity.endTime)),
|
// Text(dateFormat.format(activity.endTime)),
|
||||||
SizedBox(width: 1, height: 100, child: Container(color: Colors.white)),
|
SizedBox(width: 1, height: 100, child: Container(color: Colors.white)),
|
||||||
@@ -497,8 +508,8 @@ class _ActivitiesState extends State<Activities> {
|
|||||||
children: [
|
children: [
|
||||||
Row(mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.start, children: [
|
Row(mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.start, children: [
|
||||||
Text(name + " [$timeSpan]", style: TextStyle(fontSize: 17)),
|
Text(name + " [$timeSpan]", style: TextStyle(fontSize: 17)),
|
||||||
if (containsMetadata)Row(mainAxisAlignment:MainAxisAlignment.start,mainAxisSize: MainAxisSize.max,children: [
|
if (containsMetadata)
|
||||||
|
Row(mainAxisAlignment: MainAxisAlignment.start, mainAxisSize: MainAxisSize.max, children: [
|
||||||
Icon(
|
Icon(
|
||||||
Icons.arrow_forward_outlined,
|
Icons.arrow_forward_outlined,
|
||||||
size: 20,
|
size: 20,
|
||||||
@@ -506,10 +517,11 @@ class _ActivitiesState extends State<Activities> {
|
|||||||
SizedBox(
|
SizedBox(
|
||||||
width: MediaQuery.of(context).size.width / 3,
|
width: MediaQuery.of(context).size.width / 3,
|
||||||
child: Text(
|
child: Text(
|
||||||
activity.metadata ?? '',
|
(containsStepData)
|
||||||
|
? activity.metadata!.substring(activity.metadata!.indexOf(']') + 1)
|
||||||
|
: (activity.metadata ?? ''),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
]),
|
]),
|
||||||
// Icon(Icons.analytics, color: color, size: 20,),
|
// Icon(Icons.analytics, color: color, size: 20,),
|
||||||
]),
|
]),
|
||||||
@@ -523,14 +535,29 @@ class _ActivitiesState extends State<Activities> {
|
|||||||
),
|
),
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
(activity.taskType.relatedProject!= null) ?Container(
|
(activity.taskType.relatedProject != null)
|
||||||
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 2),
|
? Row(
|
||||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(10), color: Colors.black26),
|
children: [
|
||||||
child: Text(activity.taskType.relatedProject!.name ?? 'n/a')) : Container(),
|
if (containsStepData)
|
||||||
SizedBox(width: 10,),
|
|
||||||
Container(
|
Container(
|
||||||
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 2),
|
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 2),
|
||||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(10), color: (productive) ? Colors.green : Colors.red),
|
decoration: BoxDecoration(borderRadius: BorderRadius.circular(10), color: Colors.black26),
|
||||||
|
child: Text(activity.metadata!.substring(1, activity.metadata!.indexOf(']')) ?? 'n/a')),
|
||||||
|
SizedBox(width: 8 ,),
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 2),
|
||||||
|
decoration: BoxDecoration(borderRadius: BorderRadius.circular(10), color: Colors.black26),
|
||||||
|
child: Text(activity.taskType.relatedProject!.name ?? 'n/a')),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
: Container(),
|
||||||
|
SizedBox(
|
||||||
|
width: 10,
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 2),
|
||||||
|
decoration:
|
||||||
|
BoxDecoration(borderRadius: BorderRadius.circular(10), color: (productive) ? Colors.green : Colors.red),
|
||||||
child: Text(activity.taskType.cat?.name ?? 'n/a')),
|
child: Text(activity.taskType.cat?.name ?? 'n/a')),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
@@ -540,7 +567,8 @@ class _ActivitiesState extends State<Activities> {
|
|||||||
// : Colors.red)
|
// : Colors.red)
|
||||||
])
|
])
|
||||||
],
|
],
|
||||||
)))),
|
))
|
||||||
|
)),
|
||||||
),
|
),
|
||||||
Container(
|
Container(
|
||||||
margin: EdgeInsets.fromLTRB(15, 0, 15, 10),
|
margin: EdgeInsets.fromLTRB(15, 0, 15, 10),
|
||||||
@@ -550,14 +578,25 @@ class _ActivitiesState extends State<Activities> {
|
|||||||
)),
|
)),
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
if(selecting)InkWell(child: Container(margin:EdgeInsets.all(10),child: Icon(Icons.edit)),onTap: (){
|
if (selecting)
|
||||||
|
InkWell(
|
||||||
|
child: Container(margin: EdgeInsets.all(10), child: Icon(Icons.edit)),
|
||||||
|
onTap: () {
|
||||||
selecting = false;
|
selecting = false;
|
||||||
selectedActivities = [];
|
selectedActivities = [];
|
||||||
setState(() {
|
setState(() {});
|
||||||
|
Navigator.of(context)
|
||||||
});
|
.push(MaterialPageRoute(
|
||||||
Navigator.of(context).push(MaterialPageRoute(builder: (context) => NewActivity(sTime: activity.trueStartTime,eTime: activity.trueEndTime,metadata: activity.metadata,selectedTask: activity.taskType.name,))).then((value) => UpdateList());
|
builder: (context) => NewActivity(
|
||||||
},)
|
sTime: activity.trueStartTime,
|
||||||
|
eTime: activity.trueEndTime,
|
||||||
|
metadata: activity.metadata,
|
||||||
|
selectedTask: activity.taskType.name +
|
||||||
|
((activity.taskType.relatedProject != null) ? ' [${activity.taskType.relatedProject!.name}]' : ''),
|
||||||
|
)))
|
||||||
|
.then((value) => UpdateList());
|
||||||
|
},
|
||||||
|
)
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -592,5 +631,4 @@ class ActivityListDateGroup{
|
|||||||
List<Widget> activities;
|
List<Widget> activities;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
List<Activity> selectedActivities = [];
|
List<Activity> selectedActivities = [];
|
||||||
|
|||||||
@@ -155,7 +155,21 @@ class Journal{
|
|||||||
static String colDescription = 'Desc';
|
static String colDescription = 'Desc';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class Todo{
|
||||||
|
Todo(this.id, this.category,this.metadata, this.dueDate, {this.notificationTime, this.task});
|
||||||
|
|
||||||
|
String id;
|
||||||
|
String category;
|
||||||
|
TaskType? task;
|
||||||
|
String metadata;
|
||||||
|
DateTime dueDate;
|
||||||
|
DateTime? notificationTime;
|
||||||
|
|
||||||
|
static String colCat = 'category';
|
||||||
|
static String colMetadata = 'metadata';
|
||||||
|
static String colDueDate = 'due_date';
|
||||||
|
static String colNotificationTime = 'notification_time';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class Settings{
|
class Settings{
|
||||||
|
|||||||
@@ -310,6 +310,60 @@ class Dialogs{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static showJournalLink(DateTime date) async{
|
||||||
|
context=navigatorKey.currentContext;
|
||||||
|
|
||||||
|
if(context!=null) {
|
||||||
|
int journalId = -1;
|
||||||
|
for (int i =0; i < User.journal.length; i++) {
|
||||||
|
print('${User.journal[i].day } : $date');
|
||||||
|
if(DateFormat('yyyy-MM-dd').format(User.journal[i].day) == DateFormat('yyyy-MM-dd').format(date)){
|
||||||
|
journalId = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(journalId < 0){return;}
|
||||||
|
String title= '${(User.journal[journalId].title!= null && User.journal[journalId].title!.isNotEmpty) ? User.journal[journalId].title : DateFormat('MMMM-dd').format(date)}';
|
||||||
|
String description = User.journal[journalId].description ?? '';
|
||||||
|
if(description.length > 60){
|
||||||
|
description = description.substring(0,60) + '...(click more for more)';
|
||||||
|
}
|
||||||
|
return showDialog(
|
||||||
|
context: context!,
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
return AlertDialog(
|
||||||
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(30)),
|
||||||
|
backgroundColor: Color(0xFF1C1C1C),
|
||||||
|
title: Text(title),
|
||||||
|
content: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(description)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
MaterialButton(
|
||||||
|
onPressed: (){
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
child: Text('No', style:TextStyle(color: Colors.red)),
|
||||||
|
),
|
||||||
|
MaterialButton(
|
||||||
|
onPressed: (){
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
child: Text('Yes', style:TextStyle(color: Colors.green)),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}else{
|
||||||
|
print('context is null');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static hide(){
|
static hide(){
|
||||||
showing=false;
|
showing=false;
|
||||||
Navigator.of(navigatorKey.currentContext!).popUntil((route){
|
Navigator.of(navigatorKey.currentContext!).popUntil((route){
|
||||||
|
|||||||
@@ -80,6 +80,9 @@ class _JournalPageState extends State<JournalPage>{
|
|||||||
|
|
||||||
});
|
});
|
||||||
},child: Container(margin:EdgeInsets.all(8),child: Icon(Icons.cancel))),
|
},child: Container(margin:EdgeInsets.all(8),child: Icon(Icons.cancel))),
|
||||||
|
if(!selecting)InkWell(onTap:(){setState(() {
|
||||||
|
|
||||||
|
});},child: Container(margin: EdgeInsets.all(8), child: Icon(Icons.refresh),))
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -37,11 +37,13 @@ bool editing = false;
|
|||||||
bool multiLine = true;
|
bool multiLine = true;
|
||||||
String selectedCat = User.categories[0].name;
|
String selectedCat = User.categories[0].name;
|
||||||
|
|
||||||
|
String oldName = '[]';
|
||||||
class _NewProjectState extends State<NewProject> {
|
class _NewProjectState extends State<NewProject> {
|
||||||
|
|
||||||
_NewProjectState({bool? multiline, String? pname, String? selectedCategory, List<ProjectStep>? m_steps, int? m_eta}){
|
_NewProjectState({bool? multiline, String? pname, String? selectedCategory, List<ProjectStep>? m_steps, int? m_eta}){
|
||||||
multiLine=multiline ?? true;
|
multiLine=multiline ?? true;
|
||||||
nameController.text = pname ?? '';
|
nameController.text = pname ?? '';
|
||||||
|
if(pname!=null){oldName=pname;}
|
||||||
if(selectedCategory!=null){selectedCat = selectedCategory;}
|
if(selectedCategory!=null){selectedCat = selectedCategory;}
|
||||||
if(m_steps!=null){steps=m_steps;}else{print('no steps?');}
|
if(m_steps!=null){steps=m_steps;}else{print('no steps?');}
|
||||||
if(multiline!=null && pname != null && selectedCategory != null && m_steps!=null){
|
if(multiline!=null && pname != null && selectedCategory != null && m_steps!=null){
|
||||||
@@ -500,7 +502,12 @@ class _NewProject2State extends State<NewProject2> {
|
|||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
style: ElevatedButton.styleFrom(primary: Colors.green, shape: StadiumBorder()),
|
style: ElevatedButton.styleFrom(primary: Colors.green, shape: StadiumBorder()),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
|
if(editing){
|
||||||
|
OnClickEdit();
|
||||||
|
}else{
|
||||||
|
|
||||||
OnClickAdd();
|
OnClickAdd();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
child: Text((editing) ? 'Apply' : 'Add', style: TextStyle(fontSize: 20))))),
|
child: Text((editing) ? 'Apply' : 'Add', style: TextStyle(fontSize: 20))))),
|
||||||
],
|
],
|
||||||
@@ -688,6 +695,16 @@ class _NewProject2State extends State<NewProject2> {
|
|||||||
return route.isFirst;
|
return route.isFirst;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OnClickEdit() async{
|
||||||
|
if(projectName==null || deadline.isBefore(DateTime.now())){showAlertDialog(context, 'Error', 'Please make sure you have entered correct information'); return;}
|
||||||
|
|
||||||
|
User.UserOperations.editProject(oldName,projectName!, selectedCat, steps,etaHours, deadline);
|
||||||
|
|
||||||
|
Navigator.of(navigatorKey.currentContext!).popUntil((route){
|
||||||
|
return route.isFirst;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import 'package:tasktracker/NewProject.dart';
|
|||||||
import 'Data.dart';
|
import 'Data.dart';
|
||||||
import 'User.dart' as User;
|
import 'User.dart' as User;
|
||||||
|
|
||||||
DateFormat dateFormat = DateFormat("yyyy-MM-dd HH:mm:ss");
|
DateFormat dateTimeFormat = DateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
DateFormat durationFormat = DateFormat("HH:mm:ss");
|
DateFormat durationFormat = DateFormat("HH:mm:ss");
|
||||||
|
|
||||||
class NewTask extends StatefulWidget {
|
class NewTask extends StatefulWidget {
|
||||||
|
|||||||
337
lib/NewTodo.dart
Normal file
337
lib/NewTodo.dart
Normal file
@@ -0,0 +1,337 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/painting.dart';
|
||||||
|
import 'package:flutter_datetime_picker/flutter_datetime_picker.dart';
|
||||||
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:tasktracker/NewTask.dart';
|
||||||
|
import 'package:tasktracker/NotificationsManager.dart';
|
||||||
|
import 'Data.dart';
|
||||||
|
import 'Dialogs.dart';
|
||||||
|
import 'User.dart' as User;
|
||||||
|
|
||||||
|
DateFormat dateFormat = DateFormat("yyyy-MM-dd");
|
||||||
|
DateFormat dateTimeFormat = DateFormat("yyyy-MM-dd HH:mm");
|
||||||
|
DateFormat durationFormat = DateFormat("HH:mm:ss");
|
||||||
|
|
||||||
|
class NewTodo extends StatefulWidget {
|
||||||
|
NewTodo({Key? key, this.selectedTask, this.metadata, this.dueDate,this.notificationTime}) : super(key: key);
|
||||||
|
late String? metadata;
|
||||||
|
late String? selectedTask;
|
||||||
|
late DateTime? dueDate;
|
||||||
|
late DateTime? notificationTime;
|
||||||
|
@override
|
||||||
|
_NewActivity createState() => _NewActivity(selectedCat: selectedTask, metadata: metadata);
|
||||||
|
}
|
||||||
|
|
||||||
|
class _NewActivity extends State<NewTodo> {
|
||||||
|
late String init_selectedTask;
|
||||||
|
_NewActivity({String? metadata, String? selectedCat, DateTime? DueDate, this.notificationTime}) {
|
||||||
|
editing =selectedCat != null && DueDate !=null;
|
||||||
|
dueDate = DueDate ?? DateTime.now().add(Duration(days: 1));
|
||||||
|
this.metadataController.text = metadata ?? "";
|
||||||
|
if(this.metadataController.text.contains('[') && this.metadataController.text.contains(']') ){
|
||||||
|
this.metadataController.text = this.metadataController.text.substring(this.metadataController.text.indexOf(']')+1);
|
||||||
|
selectedStep = metadata!.substring(1,metadata!.indexOf(']'));
|
||||||
|
}else{
|
||||||
|
selectedStep='None';
|
||||||
|
}
|
||||||
|
this.init_selectedTask = this.selectedCat = selectedCat ?? User.taskTypes[0].name;
|
||||||
|
print(" meta:$metadata, task: $selectedCat");
|
||||||
|
}
|
||||||
|
|
||||||
|
TextEditingController metadataController = TextEditingController();
|
||||||
|
late String selectedCat;
|
||||||
|
late DateTime dueDate;
|
||||||
|
DateTime? notificationTime;
|
||||||
|
|
||||||
|
bool editing = false;
|
||||||
|
Map<String, TaskType?> taskTypes = <String, TaskType?>{};
|
||||||
|
Map<String, TaskType?> getActivities() {
|
||||||
|
Map<String, TaskType?> _cats = <String, TaskType?>{};
|
||||||
|
_cats.putIfAbsent("+Add New Task Type", () => null);
|
||||||
|
if (User.taskTypes.isEmpty) {
|
||||||
|
} else {
|
||||||
|
print(User.taskTypes[0].name + " : " + selectedCat);
|
||||||
|
}
|
||||||
|
User.taskTypes.forEach((element) {
|
||||||
|
String name = element.name;
|
||||||
|
if (_cats.keys.toString().contains(element.name)) {
|
||||||
|
} else {
|
||||||
|
String displayName = (name + ((element.relatedProject != null) ? ' [${element.relatedProject!.name}]' : ''));
|
||||||
|
_cats.putIfAbsent(displayName, () => element);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return _cats;
|
||||||
|
}
|
||||||
|
|
||||||
|
String? selectedStep = null;
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
taskTypes = getActivities();
|
||||||
|
bool canSelectStep = false;
|
||||||
|
List<String> steps = ['None'];
|
||||||
|
if (taskTypes[selectedCat] != null) {
|
||||||
|
if (taskTypes[selectedCat]!.relatedProject != null) {
|
||||||
|
//Got a project. But is it multi step?
|
||||||
|
if (taskTypes[selectedCat]!.relatedProject!.steps.isNotEmpty) {
|
||||||
|
canSelectStep = true;
|
||||||
|
bool matchesSelectedStep = false;
|
||||||
|
taskTypes[selectedCat]!.relatedProject!.steps.forEach((element) {
|
||||||
|
if (element.finishedDate == null) {
|
||||||
|
steps.add(element.stepName);
|
||||||
|
if (selectedStep == null) {
|
||||||
|
selectedStep = element.stepName;
|
||||||
|
matchesSelectedStep = true;
|
||||||
|
}
|
||||||
|
if (element.stepName == selectedStep) {
|
||||||
|
matchesSelectedStep = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (!matchesSelectedStep) {
|
||||||
|
selectedStep = steps[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(title: Text((editing) ? 'Edit To-Do' : 'New To-Do')),
|
||||||
|
body: Column(mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
|
||||||
|
Expanded(
|
||||||
|
flex: 9,
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
scrollDirection: Axis.vertical,
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.fromLTRB(20, 10, 20, 10),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Column(children: [
|
||||||
|
Container(padding: EdgeInsets.all(10), child: Text('Task')),
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 1),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.black12, borderRadius: BorderRadius.circular(12), border: Border.all(color: Colors.grey, width: 2)),
|
||||||
|
child: DropdownButton<String>(
|
||||||
|
dropdownColor: Color(0xFF222222),
|
||||||
|
iconSize: 30,
|
||||||
|
elevation: 10,
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
value: selectedCat,
|
||||||
|
isExpanded: true,
|
||||||
|
items: getActivities().keys.map<DropdownMenuItem<String>>((String value) {
|
||||||
|
print(value);
|
||||||
|
return DropdownMenuItem<String>(
|
||||||
|
value: value,
|
||||||
|
child: Text(value),
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
onChanged: (String? _value) {
|
||||||
|
if (_value == '+Add New Task Type') {
|
||||||
|
Navigator.of(context).push(MaterialPageRoute(builder: (context) => NewTask())).then((val) {
|
||||||
|
setState(() {});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
selectedCat = _value ?? 'n/a';
|
||||||
|
}
|
||||||
|
setState(() {});
|
||||||
|
})),
|
||||||
|
if (canSelectStep) Container(padding: EdgeInsets.all(10), child: Text('Step')),
|
||||||
|
if (canSelectStep)
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 1),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.black12, borderRadius: BorderRadius.circular(12), border: Border.all(color: Colors.grey, width: 2)),
|
||||||
|
child: DropdownButton<String>(
|
||||||
|
dropdownColor: Color(0xFF222222),
|
||||||
|
iconSize: 30,
|
||||||
|
elevation: 10,
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
value: selectedStep,
|
||||||
|
isExpanded: true,
|
||||||
|
items: steps.map<DropdownMenuItem<String>>((String value) {
|
||||||
|
print(value);
|
||||||
|
return DropdownMenuItem<String>(
|
||||||
|
value: value,
|
||||||
|
child: Text(value),
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
onChanged: (String? _value) {
|
||||||
|
selectedStep = _value;
|
||||||
|
setState(() {});
|
||||||
|
})),
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.all(10),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
TextField(
|
||||||
|
controller: metadataController,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
hintText: 'Description (required)',
|
||||||
|
filled: true,
|
||||||
|
border: OutlineInputBorder(borderRadius: BorderRadius.circular(20))),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)),
|
||||||
|
Container(
|
||||||
|
child: Divider(
|
||||||
|
)),
|
||||||
|
ListTile(
|
||||||
|
leading: FaIcon(FontAwesomeIcons.calendarDay),
|
||||||
|
title: Text('Due Date'),
|
||||||
|
subtitle: Text('When do you want to do this?'),
|
||||||
|
onTap:(){setState(() {
|
||||||
|
DatePicker.showDatePicker(context, showTitleActions: true, onChanged: (date) {
|
||||||
|
// print('change $date');
|
||||||
|
}, onConfirm: (date) {
|
||||||
|
setState(() {
|
||||||
|
dueDate=date;
|
||||||
|
});
|
||||||
|
}, currentTime: dueDate, locale: LocaleType.en);
|
||||||
|
});} ,
|
||||||
|
trailing: InkWell(
|
||||||
|
child:Text(dateFormat.format(dueDate), style: TextStyle(color: Colors.blue))
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Divider(),
|
||||||
|
|
||||||
|
ListTile(
|
||||||
|
title: Text('Notification'),
|
||||||
|
leading: FaIcon((notificationTime==null) ?FontAwesomeIcons.bellSlash :FontAwesomeIcons.bell),
|
||||||
|
trailing: Switch.adaptive(value: notificationTime!=null, onChanged: (val){
|
||||||
|
if(notificationTime==null){
|
||||||
|
notificationTime = DateTime.now().add(Duration(days: 1));
|
||||||
|
}else{
|
||||||
|
notificationTime = null;
|
||||||
|
}
|
||||||
|
setState(() {
|
||||||
|
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
]),
|
||||||
|
ListTile(
|
||||||
|
enabled: notificationTime!=null,
|
||||||
|
leading: FaIcon(FontAwesomeIcons.clock),
|
||||||
|
title: Text('Notify me at'),
|
||||||
|
subtitle: Text('When do you want to do this?'),
|
||||||
|
onTap:(){setState(() {
|
||||||
|
DatePicker.showDateTimePicker(context, showTitleActions: true, onChanged: (date) {
|
||||||
|
// print('change $date');
|
||||||
|
}, onConfirm: (date) {
|
||||||
|
setState(() {
|
||||||
|
notificationTime=date;
|
||||||
|
});
|
||||||
|
}, currentTime: notificationTime, locale: LocaleType.en);
|
||||||
|
});} ,
|
||||||
|
trailing: InkWell(
|
||||||
|
child:Text(dateTimeFormat.format(notificationTime ?? DateTime.now()), style: TextStyle(color: Colors.blue))
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
flex: 1,
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 10, horizontal: 20),
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
flex: 5,
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 0),
|
||||||
|
child: ElevatedButton(
|
||||||
|
style: ElevatedButton.styleFrom(primary: Colors.red, shape: StadiumBorder()),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
child: Text('Back', style: TextStyle(fontSize: 20))))),
|
||||||
|
Expanded(
|
||||||
|
flex: 6,
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 0),
|
||||||
|
child: ElevatedButton(
|
||||||
|
style: ElevatedButton.styleFrom(primary: Colors.green, shape: StadiumBorder()),
|
||||||
|
onPressed: () {
|
||||||
|
if (editing) {
|
||||||
|
edit_action();
|
||||||
|
} else {
|
||||||
|
add_action();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Text((editing) ? 'Apply' : 'Add Todo', style: TextStyle(fontSize: 20))))),
|
||||||
|
],
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget QuickTimeButton(text, {Function}) {
|
||||||
|
return InkWell(
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 15),
|
||||||
|
height: 30,
|
||||||
|
decoration: BoxDecoration(color: Colors.blueAccent, borderRadius: BorderRadius.circular(50)),
|
||||||
|
child: Align(
|
||||||
|
child: Text(text),
|
||||||
|
alignment: Alignment.center,
|
||||||
|
)),
|
||||||
|
onTap: () {
|
||||||
|
Function();
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_action() async {
|
||||||
|
if(metadataController.text.isEmpty){
|
||||||
|
Dialogs.showAlertDialog(context, 'Invalid data', 'Please enter description to add new todo');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await User.UserOperations.addTodo(selectedCat, metadataController.text, dueDate, notificationTime);
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void edit_action() async {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String _printDuration(Duration duration) {
|
||||||
|
String twoDigits(int n) => n.toString().padLeft(2, "0");
|
||||||
|
String twoDigitMinutes = twoDigits(duration.inMinutes.remainder(60));
|
||||||
|
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;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'User.dart' as User;
|
|
||||||
import 'main.dart';
|
|
||||||
class TodoPage extends StatefulWidget {
|
|
||||||
const TodoPage({Key? key}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<TodoPage> createState() => _TodoPageState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _TodoPageState extends State<TodoPage> {
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return SafeArea(child: Scaffold(
|
|
||||||
floatingActionButton: FloatingActionButton.extended(
|
|
||||||
onPressed: () {
|
|
||||||
// Navigator.of(context).push(MaterialPageRoute(builder: (context) => NewTodo())).then((value) => {User.refreshUserData().then((va) => {})});
|
|
||||||
},
|
|
||||||
label: Text("New Todo"),
|
|
||||||
icon: Icon(Icons.add)),
|
|
||||||
appBar: AppBar(
|
|
||||||
title: Column(
|
|
||||||
mainAxisSize: MainAxisSize.max,
|
|
||||||
mainAxisAlignment: MainAxisAlignment.end,
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
mainAxisSize: MainAxisSize.max,
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
Row(children: [Icon(Icons.check, color: Theme.of(context).primaryColor), SizedBox(width: 10), Text('Todo')]),
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
(User.offline)
|
|
||||||
? Icon(Icons.signal_cellular_connected_no_internet_4_bar_outlined)
|
|
||||||
: InkWell(
|
|
||||||
onTap: () {
|
|
||||||
setState(() {
|
|
||||||
//LoadStats();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
child: Icon(Icons.refresh, size: 30),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
//Container(color: Colors.red,child: Text("Offline",style:TextStyle(fontSize: 5))),
|
|
||||||
],
|
|
||||||
)),
|
|
||||||
drawer: navDrawer(context, 7),
|
|
||||||
body: Column(
|
|
||||||
children: PrintTodos(),
|
|
||||||
),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Widget> PrintTodos(){
|
|
||||||
List<Widget> todos = [];
|
|
||||||
|
|
||||||
todos.forEach((element) {
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
todos.add(prioritySeperator('- High Priority (0)'));
|
|
||||||
todos.add(prioritySeperator('- Low Priority (0)'));
|
|
||||||
|
|
||||||
return todos;
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget todoItem(String name){
|
|
||||||
return Row(children:[Text(name)]);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget prioritySeperator(String text){
|
|
||||||
return Padding(
|
|
||||||
padding: const EdgeInsets.fromLTRB(15,15,15,0),
|
|
||||||
child: Row(
|
|
||||||
children: [Text(text,style:TextStyle(fontSize: 18, color: Colors.grey))],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
278
lib/Todos.dart
Normal file
278
lib/Todos.dart
Normal file
@@ -0,0 +1,278 @@
|
|||||||
|
import 'package:firebase_auth/firebase_auth.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_colorpicker/flutter_colorpicker.dart';
|
||||||
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
|
||||||
|
import 'package:tasktracker/NewJournal.dart';
|
||||||
|
import 'package:tasktracker/NewTodo.dart';
|
||||||
|
import 'package:tasktracker/main.dart';
|
||||||
|
import 'User.dart' as User;
|
||||||
|
import 'Dialogs.dart';
|
||||||
|
|
||||||
|
class TodosPage extends StatefulWidget {
|
||||||
|
const TodosPage({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<TodosPage> createState() => _TodosPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _TodosPageState extends State<TodosPage> {
|
||||||
|
bool selecting = false;
|
||||||
|
List<int> selectedIndexes = [];
|
||||||
|
int expandedIndex = -1;
|
||||||
|
var refreshStream;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
// TODO: implement initState
|
||||||
|
super.initState();
|
||||||
|
|
||||||
|
refreshStream = User.refreshStream.stream.listen((event) {
|
||||||
|
if (!event) {
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
// TODO: implement dispose
|
||||||
|
super.dispose();
|
||||||
|
refreshStream?.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
floatingActionButton: FloatingActionButton.extended(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).push(MaterialPageRoute(builder: (context) => NewTodo())).then((val) {
|
||||||
|
setState(() {});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
label: Text("New To-Do"),
|
||||||
|
icon: Icon(Icons.add)),
|
||||||
|
appBar: AppBar(
|
||||||
|
title: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
FaIcon(FontAwesomeIcons.calendarCheck),
|
||||||
|
SizedBox(
|
||||||
|
width: 15,
|
||||||
|
),
|
||||||
|
Text('To-Do')
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
if (selecting && selectedIndexes.length > 0)
|
||||||
|
InkWell(
|
||||||
|
onTap: () async {
|
||||||
|
selecting = false;
|
||||||
|
for (int element in selectedIndexes) {
|
||||||
|
await User.UserOperations.deleteJournal(User.todos[element].id);
|
||||||
|
}
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
child: Container(margin: EdgeInsets.all(8), child: Icon(Icons.delete))),
|
||||||
|
if (selecting)
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
selecting = false;
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
child: Container(margin: EdgeInsets.all(8), child: Icon(Icons.cancel))),
|
||||||
|
if (!selecting)
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
margin: EdgeInsets.all(8),
|
||||||
|
child: Icon(Icons.refresh),
|
||||||
|
))
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
drawer: navDrawer(context, 9),
|
||||||
|
body: Container(
|
||||||
|
padding: EdgeInsets.all(8),
|
||||||
|
child: ScrollablePositionedList.builder(
|
||||||
|
itemCount: User.todos.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
int maxCharCount = 100;
|
||||||
|
bool containsStepData = User.todos[index].metadata.contains('[') && User.todos[index].metadata.contains(']');
|
||||||
|
return Container(
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () {
|
||||||
|
if (selecting) {
|
||||||
|
if (selectedIndexes.contains(index)) {
|
||||||
|
selectedIndexes.remove(index);
|
||||||
|
} else {
|
||||||
|
selectedIndexes.add(index);
|
||||||
|
}
|
||||||
|
setState(() {});
|
||||||
|
} else {
|
||||||
|
if (expandedIndex == index) {
|
||||||
|
expandedIndex = -1;
|
||||||
|
//_controller..reverse(from: 0.5);
|
||||||
|
} else {
|
||||||
|
expandedIndex = index;
|
||||||
|
// _controller..forward(from: 0);
|
||||||
|
}
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onLongPress: () {
|
||||||
|
selecting = !selecting;
|
||||||
|
if (!selectedIndexes.contains(index)) {
|
||||||
|
selectedIndexes.add(index);
|
||||||
|
}
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
if (selecting)
|
||||||
|
Checkbox(
|
||||||
|
value: selectedIndexes.contains(index),
|
||||||
|
onChanged: (newVal) {
|
||||||
|
if (selectedIndexes.contains(index)) {
|
||||||
|
selectedIndexes.remove(index);
|
||||||
|
} else {
|
||||||
|
selectedIndexes.add(index);
|
||||||
|
}
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Card(
|
||||||
|
|
||||||
|
// color: color,
|
||||||
|
elevation: 30,
|
||||||
|
shadowColor: colorFromHex(User.todos[index].task!.cat!.color),
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () {
|
||||||
|
//Open Respective Category
|
||||||
|
if (selecting) {
|
||||||
|
//OnItemSelected(activity);
|
||||||
|
}
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
onLongPress: () {
|
||||||
|
print('gonna delete');
|
||||||
|
selecting = !selecting;
|
||||||
|
// selectedActivities = [activity];
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.all(15),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Row(mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.start, children: [
|
||||||
|
Text(User.todos[index].task!.name, style: TextStyle(fontSize: 17)),
|
||||||
|
Row(mainAxisAlignment: MainAxisAlignment.start, mainAxisSize: MainAxisSize.max, children: [
|
||||||
|
Icon(
|
||||||
|
Icons.arrow_forward_outlined,
|
||||||
|
size: 20,
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: MediaQuery.of(context).size.width / 3,
|
||||||
|
child: Text(
|
||||||
|
(containsStepData)
|
||||||
|
? User.todos[index].metadata.substring(User.todos[index].metadata!.indexOf(']') + 1)
|
||||||
|
: (User.todos[index].metadata ?? ''),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
// Icon(Icons.analytics, color: color, size: 20,),
|
||||||
|
]),
|
||||||
|
SizedBox(
|
||||||
|
height: 5,
|
||||||
|
),
|
||||||
|
Row(mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 2),
|
||||||
|
decoration: BoxDecoration(borderRadius: BorderRadius.circular(10), color: Colors.blue),
|
||||||
|
child: Text(DateFormat('yyyy-MM-dd').format(User.todos[index].dueDate))),
|
||||||
|
SizedBox(
|
||||||
|
width: 20,
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
(User.todos[index].task!.relatedProject != null)
|
||||||
|
? Row(
|
||||||
|
children: [
|
||||||
|
if (containsStepData)
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 2),
|
||||||
|
decoration:
|
||||||
|
BoxDecoration(borderRadius: BorderRadius.circular(10), color: Colors.black26),
|
||||||
|
child: Text(User.todos[index].metadata!
|
||||||
|
.substring(1, User.todos[index].metadata!.indexOf(']')) ??
|
||||||
|
'n/a')),
|
||||||
|
SizedBox(
|
||||||
|
width: 8,
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 2),
|
||||||
|
decoration:
|
||||||
|
BoxDecoration(borderRadius: BorderRadius.circular(10), color: Colors.black26),
|
||||||
|
child: Text(User.todos[index].task!.relatedProject!.name ?? 'n/a')),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
: Container(),
|
||||||
|
SizedBox(
|
||||||
|
width: 10,
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 2),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
color: (User.todos[index].task!.cat!.productive) ? Colors.green : Colors.red),
|
||||||
|
child: Text(User.todos[index].task!.cat?.name ?? 'n/a')),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
// Icon(Icons.circle,
|
||||||
|
// color: (productive)
|
||||||
|
// ? Colors.green
|
||||||
|
// : Colors.red)
|
||||||
|
])
|
||||||
|
],
|
||||||
|
)))),
|
||||||
|
Container(
|
||||||
|
margin: EdgeInsets.fromLTRB(15, 0, 15, 10),
|
||||||
|
height: 2,
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(flex: 100, child: Container(color: colorFromHex(User.todos[index].task!.cat!.color))),
|
||||||
|
Expanded(flex: 0, child: Container())
|
||||||
|
],
|
||||||
|
)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (selecting)
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
// Navigator.of(context).push(MaterialPageRoute(builder: (context) => NewJournal(date: User.todos[index].day, title: User.todos[index].title, text: User.todos[index].description,))).then((val) {
|
||||||
|
// setState(() {});
|
||||||
|
// });
|
||||||
|
selecting = false;
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
child: Container(margin: EdgeInsets.all(8), child: FaIcon(FontAwesomeIcons.edit)))
|
||||||
|
],
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
317
lib/User.dart
317
lib/User.dart
@@ -29,6 +29,7 @@ List<TaskType> taskTypes = [];
|
|||||||
List<Activity> activities = [];
|
List<Activity> activities = [];
|
||||||
List<Project> projects = [];
|
List<Project> projects = [];
|
||||||
List<Journal> journal = [];
|
List<Journal> journal = [];
|
||||||
|
List<Todo> todos = [];
|
||||||
|
|
||||||
bool offline = true;
|
bool offline = true;
|
||||||
bool registered = false;
|
bool registered = false;
|
||||||
@@ -86,8 +87,8 @@ Future<void> BuildBridgeToServer() async{
|
|||||||
while (true) {
|
while (true) {
|
||||||
await UserOperations.executeQueries();
|
await UserOperations.executeQueries();
|
||||||
try {
|
try {
|
||||||
http.Response response = (await http.post(Uri.parse('http://161.97.127.136/task_tracker/bridge.php'),
|
http.Response response =
|
||||||
body: <String, String>{"username": username}));
|
(await http.post(Uri.parse('http://161.97.127.136/task_tracker/bridge.php'), body: <String, String>{"username": username}));
|
||||||
|
|
||||||
print("bridge retreive (try): ${response.body}");
|
print("bridge retreive (try): ${response.body}");
|
||||||
List<String> data = response.body.split(",");
|
List<String> data = response.body.split(",");
|
||||||
@@ -114,12 +115,10 @@ Future<void> BuildBridgeToServer() async{
|
|||||||
prefs.setString('rev', response.body);
|
prefs.setString('rev', response.body);
|
||||||
await refreshUserData();
|
await refreshUserData();
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print("Error with bridge : $e");
|
print("Error with bridge : $e");
|
||||||
}
|
}
|
||||||
await Future.delayed(Duration(seconds: 5));
|
await Future.delayed(Duration(seconds: 5));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,7 +126,8 @@ bool m_refreshing = false;
|
|||||||
Future<void> refreshUserData({bool forceOffline = false}) async {
|
Future<void> refreshUserData({bool forceOffline = false}) async {
|
||||||
print('refreshing user data');
|
print('refreshing user data');
|
||||||
if (m_refreshing) {
|
if (m_refreshing) {
|
||||||
print('Called while refreshing. Return');return;
|
print('Called while refreshing. Return');
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
m_refreshing = true;
|
m_refreshing = true;
|
||||||
|
|
||||||
@@ -138,16 +138,16 @@ Future<void> refreshUserData({bool forceOffline = false}) async {
|
|||||||
taskTypes = await GetTaskTypes(true);
|
taskTypes = await GetTaskTypes(true);
|
||||||
activities = await GetActivities(true);
|
activities = await GetActivities(true);
|
||||||
journal = await GetJournals(true);
|
journal = await GetJournals(true);
|
||||||
|
todos = await GetTodos(true);
|
||||||
|
|
||||||
refreshStream.add(false);
|
refreshStream.add(false);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
categories = await GetCategories(false);
|
categories = await GetCategories(false);
|
||||||
projects = await GetProjects(false);
|
projects = await GetProjects(false);
|
||||||
taskTypes = await GetTaskTypes(false);
|
taskTypes = await GetTaskTypes(false);
|
||||||
activities = await GetActivities(false);
|
activities = await GetActivities(false);
|
||||||
journal = await GetJournals(false);
|
journal = await GetJournals(false);
|
||||||
|
todos= await GetTodos(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_refreshing = false;
|
m_refreshing = false;
|
||||||
@@ -156,7 +156,6 @@ Future<void> refreshUserData({bool forceOffline = false}) async {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Future<bool> cacheDbExist() async {
|
Future<bool> cacheDbExist() async {
|
||||||
if (Platform.isAndroid || Platform.isIOS) {
|
if (Platform.isAndroid || Platform.isIOS) {
|
||||||
Directory directory = await getApplicationDocumentsDirectory();
|
Directory directory = await getApplicationDocumentsDirectory();
|
||||||
@@ -202,7 +201,8 @@ void onCacheDatabaseCreate(Database db, int newVersion) async {
|
|||||||
await db.execute(CategoriesTableSQL);
|
await db.execute(CategoriesTableSQL);
|
||||||
print("Initiated Categories Table");
|
print("Initiated Categories Table");
|
||||||
|
|
||||||
String TaskTableSQL = 'CREATE TABLE TaskTypes(id TEXT PRIMARY KEY, ${TaskType.colName} TEXT, ${TaskType.colCategory} TEXT, ${TaskType.colRelatedProject} TEXT, '
|
String TaskTableSQL =
|
||||||
|
'CREATE TABLE TaskTypes(id TEXT PRIMARY KEY, ${TaskType.colName} TEXT, ${TaskType.colCategory} TEXT, ${TaskType.colRelatedProject} TEXT, '
|
||||||
'FOREIGN KEY (${TaskType.colCategory}) REFERENCES Categories(${Category.colCatId}))';
|
'FOREIGN KEY (${TaskType.colCategory}) REFERENCES Categories(${Category.colCatId}))';
|
||||||
// print(TaskTableSQL);
|
// print(TaskTableSQL);
|
||||||
await db.execute(TaskTableSQL);
|
await db.execute(TaskTableSQL);
|
||||||
@@ -219,9 +219,13 @@ void onCacheDatabaseCreate(Database db, int newVersion) async {
|
|||||||
|
|
||||||
String JournalTableSQL = 'CREATE TABLE Journal(id TEXT PRIMARY KEY, ${Journal.colTitle} TEXT, ${Journal.colDescription})';
|
String JournalTableSQL = 'CREATE TABLE Journal(id TEXT PRIMARY KEY, ${Journal.colTitle} TEXT, ${Journal.colDescription})';
|
||||||
await db.execute(JournalTableSQL);
|
await db.execute(JournalTableSQL);
|
||||||
|
|
||||||
|
String TodoTableSQL = 'CREATE TABLE Todos(id TEXT PRIMARY KEY, ${Todo.colCat} TEXT, ${Todo.colMetadata} TEXT, ${Todo.colDueDate} DATE, ${Todo.colNotificationTime} DATETIME)';
|
||||||
|
await db.execute(TodoTableSQL);
|
||||||
|
|
||||||
String QueriesTableSQL = 'CREATE TABLE Queries(id INTEGER PRIMARY KEY AUTOINCREMENT, ${Queries.colLink} TEXT,${Queries.colData} TEXT)';
|
String QueriesTableSQL = 'CREATE TABLE Queries(id INTEGER PRIMARY KEY AUTOINCREMENT, ${Queries.colLink} TEXT,${Queries.colData} TEXT)';
|
||||||
// print(QueriesTableSQL);
|
|
||||||
await db.execute(QueriesTableSQL);
|
await db.execute(QueriesTableSQL);
|
||||||
|
|
||||||
final prefs = await SharedPreferences.getInstance();
|
final prefs = await SharedPreferences.getInstance();
|
||||||
|
|
||||||
if (prefs.getBool("registered") ?? false) {
|
if (prefs.getBool("registered") ?? false) {
|
||||||
@@ -437,7 +441,8 @@ Future<void> UpdateTaskTypesFromServer() async {
|
|||||||
for (var value in data) {
|
for (var value in data) {
|
||||||
Map<String, dynamic> cat = jsonDecode(value);
|
Map<String, dynamic> cat = jsonDecode(value);
|
||||||
//print(cat);
|
//print(cat);
|
||||||
await cacheDb.rawInsert("INSERT OR REPLACE INTO TaskTypes (${TaskType.colId},${TaskType.colName},${TaskType.colCategory},${TaskType.colRelatedProject}) "
|
await cacheDb
|
||||||
|
.rawInsert("INSERT OR REPLACE INTO TaskTypes (${TaskType.colId},${TaskType.colName},${TaskType.colCategory},${TaskType.colRelatedProject}) "
|
||||||
"VALUES ('${cat['task_id']}','${cat['name']}','${cat['category_id']}', '${cat['related_project']}') ");
|
"VALUES ('${cat['task_id']}','${cat['name']}','${cat['category_id']}', '${cat['related_project']}') ");
|
||||||
|
|
||||||
print(await cacheDb.query("TaskTypes"));
|
print(await cacheDb.query("TaskTypes"));
|
||||||
@@ -447,7 +452,6 @@ Future<void> UpdateTaskTypesFromServer() async {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void StartActivityTimer(String taskType, String metadata, DateTime startTime) async {
|
void StartActivityTimer(String taskType, String metadata, DateTime startTime) async {
|
||||||
final prefs = await SharedPreferences.getInstance();
|
final prefs = await SharedPreferences.getInstance();
|
||||||
|
|
||||||
@@ -455,7 +459,6 @@ void StartActivityTimer(String taskType, String metadata, DateTime startTime) as
|
|||||||
NotificationManager.RescheduleNotifications();
|
NotificationManager.RescheduleNotifications();
|
||||||
|
|
||||||
UserOperations.startOngoing(prefs.getString('current_activity')!);
|
UserOperations.startOngoing(prefs.getString('current_activity')!);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<String>?> getOngoingData() async {
|
Future<List<String>?> getOngoingData() async {
|
||||||
@@ -465,10 +468,8 @@ Future<List<String>?> getOngoingData() async{
|
|||||||
try {
|
try {
|
||||||
data = prefs.getString('current_activity')!.split('<td>');
|
data = prefs.getString('current_activity')!.split('<td>');
|
||||||
return data;
|
return data;
|
||||||
}catch(e){
|
} catch (e) {}
|
||||||
}
|
} else {}
|
||||||
}else{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void StopActivityTimer() async {
|
void StopActivityTimer() async {
|
||||||
@@ -623,7 +624,7 @@ Future<void> UpdateActivitiesFromServer() async {
|
|||||||
//print(cat);
|
//print(cat);
|
||||||
await cacheDb.rawInsert(
|
await cacheDb.rawInsert(
|
||||||
"INSERT OR REPLACE INTO Activities (${Activity.colType}, ${Activity.colStartTime}, ${Activity.colEndTime}, ${Activity.colMetadata}) "
|
"INSERT OR REPLACE INTO Activities (${Activity.colType}, ${Activity.colStartTime}, ${Activity.colEndTime}, ${Activity.colMetadata}) "
|
||||||
"VALUES ('${cat['task_id']}', '${cat['sTime']}','${cat['eTime']}', '${cat['metadata']}') ");
|
"VALUES ('${cat['task_id']}', '${cat['sTime']}','${cat['eTime']}', '${cat['metadata'].toString().replaceAll("'", "''")}') ");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
print("No activities for now");
|
print("No activities for now");
|
||||||
@@ -670,7 +671,11 @@ Future<List<Project>> GetProjects(bool forceOffline) async {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Category? cat = await getCatFromId(category);
|
Category? cat = await getCatFromId(category);
|
||||||
if(cat==null){print('couldnt find cat');continue;}
|
print('searching for $category');
|
||||||
|
if (cat == null) {
|
||||||
|
print('couldnt find cat');
|
||||||
|
continue;
|
||||||
|
}
|
||||||
print('steps : $stepsJson');
|
print('steps : $stepsJson');
|
||||||
List<dynamic> _steps = jsonDecode(stepsJson);
|
List<dynamic> _steps = jsonDecode(stepsJson);
|
||||||
List<ProjectStep> steps = [];
|
List<ProjectStep> steps = [];
|
||||||
@@ -710,7 +715,6 @@ Future<List<Project>> GetProjects(bool forceOffline) async {
|
|||||||
print('null found');
|
print('null found');
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
projects = _projects;
|
projects = _projects;
|
||||||
@@ -810,7 +814,8 @@ Future<List<Journal>> GetJournals(bool forceOffline) async {
|
|||||||
for (var value in data) {
|
for (var value in data) {
|
||||||
Map<String, dynamic> cat = jsonDecode(value);
|
Map<String, dynamic> cat = jsonDecode(value);
|
||||||
//print(catData);
|
//print(catData);
|
||||||
_categories.add(Journal(cat['id'],DateTime.parse(cat['id'].toString().replaceAll(username, '')), title:cat['title'], description:cat['text']));
|
_categories
|
||||||
|
.add(Journal(cat['id'], DateTime.parse(cat['id'].toString().replaceAll(username, '')), title: cat['title'], description: cat['text']));
|
||||||
}
|
}
|
||||||
journal = _categories;
|
journal = _categories;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -833,8 +838,7 @@ Future<void> UpdateJournalsFromServer() async {
|
|||||||
for (var value in data) {
|
for (var value in data) {
|
||||||
Map<String, dynamic> cat = jsonDecode(value);
|
Map<String, dynamic> cat = jsonDecode(value);
|
||||||
//print(catData);
|
//print(catData);
|
||||||
await cacheDb
|
await cacheDb.rawInsert("INSERT OR REPLACE INTO Journal (id, ${Journal.colTitle},${Journal.colDescription}) "
|
||||||
.rawInsert("INSERT OR REPLACE INTO Journal (id, ${Journal.colTitle},${Journal.colDescription}) "
|
|
||||||
"VALUES ('${cat['id']}','${cat['title'].toString().replaceAll("'", "''")}','${cat['description'].toString().replaceAll("'", "''")}') ");
|
"VALUES ('${cat['id']}','${cat['title'].toString().replaceAll("'", "''")}','${cat['description'].toString().replaceAll("'", "''")}') ");
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -842,6 +846,100 @@ Future<void> UpdateJournalsFromServer() async {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<List<Todo>> GetTodos(bool forceOffline) async {
|
||||||
|
if (cacheEnabled) {
|
||||||
|
List<Todo> _todos = [];
|
||||||
|
if (offline || forceOffline) {
|
||||||
|
//Retreive from cacheDB
|
||||||
|
|
||||||
|
} else {
|
||||||
|
//Check if server got updated, If not go for cache
|
||||||
|
|
||||||
|
//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);
|
||||||
|
// }
|
||||||
|
|
||||||
|
//Update CacheDB
|
||||||
|
if (!catsUpdated) {
|
||||||
|
await UpdateTodosFromServer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Map> cats = await cacheDb.query('Todos');
|
||||||
|
print(cats.length);
|
||||||
|
for (Map element in cats) {
|
||||||
|
String? id = element['id'].toString();
|
||||||
|
String? task_id = element[Todo.colCat];
|
||||||
|
String? metadata = element[Todo.colMetadata];
|
||||||
|
String? due_date = element[Todo.colDueDate];
|
||||||
|
String? notification_time = element[Todo.colNotificationTime];
|
||||||
|
|
||||||
|
if (id == null || task_id == null || metadata == null || due_date == null) {
|
||||||
|
print("Something is null!");
|
||||||
|
print("id:{$id}, task:{$task_id}, metadata:${metadata}, due_date: ${due_date}");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
TaskType? taskType = await getTaskFromId(task_id);
|
||||||
|
if(taskType == null){print('got null taask for this todo!');print("id:{$id}, task:{$task_id}, metadata:${metadata}, due_date: ${due_date}");}
|
||||||
|
DateTime dueDate = DateTime.parse(due_date);
|
||||||
|
DateTime? notificationTime = (notification_time == null) ? null : ((notification_time.isEmpty || notification_time =='null') ? null :DateTime.parse(notification_time));
|
||||||
|
// print("name:{$catName}, color:{$catColor}, prod:{$catProductive}");
|
||||||
|
_todos.add(Todo(id,task_id,metadata,dueDate, notificationTime: notificationTime, task:taskType));
|
||||||
|
}
|
||||||
|
todos = _todos;
|
||||||
|
} else {
|
||||||
|
print("NC: Updating todos as $username");
|
||||||
|
try {
|
||||||
|
http.Response response = (await http.post(Uri.parse('http://161.97.127.136/task_tracker/get_todos.php'),
|
||||||
|
body: <String, String>{"username": username, "device_id": await Settings.UUID()}));
|
||||||
|
|
||||||
|
print(response.body);
|
||||||
|
List<String> data = response.body.split("<td>");
|
||||||
|
List<Journal> _categories = [];
|
||||||
|
for (var value in data) {
|
||||||
|
Map<String, dynamic> cat = jsonDecode(value);
|
||||||
|
//print(catData);
|
||||||
|
_categories
|
||||||
|
.add(Journal(cat['id'], DateTime.parse(cat['id'].toString().replaceAll(username, '')), title: cat['title'], description: cat['text']));
|
||||||
|
}
|
||||||
|
journal = _categories;
|
||||||
|
} catch (e) {
|
||||||
|
print("Error while cats NC: $e");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// journal.sort((a, b) => b.day.compareTo(a.day));
|
||||||
|
return todos;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> UpdateTodosFromServer() async {
|
||||||
|
print("Updating Todos as $username");
|
||||||
|
try {
|
||||||
|
http.Response response = (await http.post(Uri.parse('http://161.97.127.136/task_tracker/get_todos.php'),
|
||||||
|
body: <String, String>{"username": username, "device_id": await Settings.UUID()}));
|
||||||
|
|
||||||
|
print(response.body);
|
||||||
|
List<String> data = response.body.split("<td>");
|
||||||
|
await cacheDb.delete("Todos");
|
||||||
|
for (var value in data) {
|
||||||
|
Map<String, dynamic> cat = jsonDecode(value);
|
||||||
|
//print(catData);
|
||||||
|
await cacheDb.rawInsert("INSERT OR REPLACE INTO Todos (id, ${Todo.colCat},${Todo.colMetadata},${Todo.colDueDate},${Todo.colNotificationTime}) "
|
||||||
|
"VALUES ('${cat['id'].toString().replaceAll("'", "''")}', '${cat['task_id']}', '${cat['metadata'].toString().replaceAll("'", "''")}', '${cat['due_date']}', '${cat['notification_time']}') ");
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
print("Error while cats $e");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Future<TaskType?> getTaskFromId(String taskId) async {
|
Future<TaskType?> getTaskFromId(String taskId) async {
|
||||||
// await GetTaskTypes(false);
|
// await GetTaskTypes(false);
|
||||||
TaskType? cat = null;
|
TaskType? cat = null;
|
||||||
@@ -885,6 +983,19 @@ Future<Project?> getProjectFromId(String projectId) async {
|
|||||||
return project;
|
return project;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool journalExists(DateTime date){
|
||||||
|
int journalId = -1;
|
||||||
|
for (int i =0; i < journal.length; i++) {
|
||||||
|
// print('${journal[i].day } : $date');
|
||||||
|
if(DateFormat('yyyy-MM-dd').format(journal[i].day) == DateFormat('yyyy-MM-dd').format(date)){
|
||||||
|
journalId = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (journalId > 0);
|
||||||
|
}
|
||||||
|
|
||||||
//Helpers
|
//Helpers
|
||||||
class Helpers {
|
class Helpers {
|
||||||
Future<String?> _getId() async {
|
Future<String?> _getId() async {
|
||||||
@@ -969,8 +1080,14 @@ class UserOperations {
|
|||||||
await cacheDb.insert('Queries', query);
|
await cacheDb.insert('Queries', query);
|
||||||
|
|
||||||
//update Cache
|
//update Cache
|
||||||
Map<String, Object> data = {TaskType.colId: username + name, Category.colName: name, Category.colCatId: username + category,};
|
Map<String, Object> data = {
|
||||||
if(relatedProject!=null || relatedProject =='None'){data.putIfAbsent(TaskType.colRelatedProject, () => relatedProject.toString());}
|
TaskType.colId: username + name,
|
||||||
|
Category.colName: name,
|
||||||
|
Category.colCatId: username + category,
|
||||||
|
};
|
||||||
|
if (relatedProject != null || relatedProject == 'None') {
|
||||||
|
data.putIfAbsent(TaskType.colRelatedProject, () => relatedProject.toString());
|
||||||
|
}
|
||||||
await cacheDb.insert('TaskTypes', data);
|
await cacheDb.insert('TaskTypes', data);
|
||||||
await refreshUserData(forceOffline: true);
|
await refreshUserData(forceOffline: true);
|
||||||
} else {
|
} else {
|
||||||
@@ -1008,7 +1125,8 @@ class UserOperations {
|
|||||||
await cacheDb.insert('Queries', query);
|
await cacheDb.insert('Queries', query);
|
||||||
|
|
||||||
//update Cache
|
//update Cache
|
||||||
await cacheDb.rawUpdate("UPDATE TaskTypes SET ${TaskType.colId}='${username+name}', ${TaskType.colName}='$name', ${TaskType.colCategory}='${username+category}', ${TaskType.colRelatedProject}='${(relatedProject == 'None') ? '' : relatedProject}' WHERE id='${username+oldName}'");
|
await cacheDb.rawUpdate(
|
||||||
|
"UPDATE TaskTypes SET ${TaskType.colId}='${username + name}', ${TaskType.colName}='$name', ${TaskType.colCategory}='${username + category}', ${TaskType.colRelatedProject}='${(relatedProject == 'None') ? '' : relatedProject}' WHERE id='${username + oldName}'");
|
||||||
await refreshUserData(forceOffline: true);
|
await refreshUserData(forceOffline: true);
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
@@ -1213,7 +1331,13 @@ class UserOperations {
|
|||||||
await cacheDb.insert('Queries', query);
|
await cacheDb.insert('Queries', query);
|
||||||
|
|
||||||
//update Cache
|
//update Cache
|
||||||
Map<String, Object> data = {Project.colName: username+name, Project.colCat: category, Project.colSteps: jsonEncode(steps),Project.colEta: eta, Project.colDeadline: deadline.toString()};
|
Map<String, Object> data = {
|
||||||
|
Project.colName: username + name,
|
||||||
|
Project.colCat: category,
|
||||||
|
Project.colSteps: jsonEncode(steps),
|
||||||
|
Project.colEta: eta,
|
||||||
|
Project.colDeadline: deadline.toString()
|
||||||
|
};
|
||||||
await cacheDb.insert('Projects', data);
|
await cacheDb.insert('Projects', data);
|
||||||
await refreshUserData(forceOffline: true);
|
await refreshUserData(forceOffline: true);
|
||||||
} else {
|
} else {
|
||||||
@@ -1231,8 +1355,52 @@ class UserOperations {
|
|||||||
await executeQueries();
|
await executeQueries();
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<void> CompleteProjectStep(Project project, ProjectStep step, DateTime finishedDate) async {
|
static Future<void> editProject(String oldName, String name, String category, List<ProjectStep> steps, int eta, DateTime deadline) async {
|
||||||
|
Map<String, String> queryBody = <String, String>{
|
||||||
|
'oldName': username + oldName,
|
||||||
|
'name': username + name,
|
||||||
|
'username': username,
|
||||||
|
'category_id': username + category,
|
||||||
|
'steps': jsonEncode(steps),
|
||||||
|
'eta': eta.toString(),
|
||||||
|
'deadline': DateFormat("yyyy-MM-dd").format(deadline)
|
||||||
|
};
|
||||||
|
|
||||||
|
if (cacheEnabled) {
|
||||||
|
//Add Query
|
||||||
|
Map<String, Object> query = {Queries.colLink: 'edit_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 = {
|
||||||
|
Project.colName: username + name,
|
||||||
|
Project.colCat: category,
|
||||||
|
Project.colSteps: jsonEncode(steps),
|
||||||
|
Project.colEta: eta,
|
||||||
|
Project.colDeadline: deadline.toString()
|
||||||
|
};
|
||||||
|
await cacheDb.rawUpdate(
|
||||||
|
"UPDATE Projects SET ${Project.colName}='${username + name}', ${Project.colCat}='${username+category}', ${Project.colSteps}='${jsonEncode(steps)}', ${Project.colEta}='${eta}', ${Project.colDeadline}='${deadline.toString()}' WHERE ${Project.colName}='${username+oldName}'");
|
||||||
|
await cacheDb.rawUpdate("UPDATE TaskTypes SET ${TaskType.colRelatedProject}='${username+name}' WHERE ${TaskType.colRelatedProject}='${username+oldName}'");
|
||||||
|
await refreshUserData(forceOffline: true);
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
http.Response queryResponse = (await http.post(Uri.parse('http://161.97.127.136/task_tracker/edit_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> CompleteProjectStep(Project project, ProjectStep step, DateTime finishedDate) async {
|
||||||
project.steps.forEach((element) {
|
project.steps.forEach((element) {
|
||||||
if (element.stepName == step.stepName) {
|
if (element.stepName == step.stepName) {
|
||||||
element.finishedDate = finishedDate;
|
element.finishedDate = finishedDate;
|
||||||
@@ -1273,7 +1441,6 @@ class UserOperations {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static Future<void> UndoProjectStep(Project project, ProjectStep step) async {
|
static Future<void> UndoProjectStep(Project project, ProjectStep step) async {
|
||||||
|
|
||||||
project.steps.forEach((element) {
|
project.steps.forEach((element) {
|
||||||
if (element.stepName == step.stepName) {
|
if (element.stepName == step.stepName) {
|
||||||
element.finishedDate = null;
|
element.finishedDate = null;
|
||||||
@@ -1314,7 +1481,6 @@ class UserOperations {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static Future<void> addJournal(DateTime day, String title, String text) async {
|
static Future<void> addJournal(DateTime day, String title, String text) async {
|
||||||
|
|
||||||
bool exist = false;
|
bool exist = false;
|
||||||
for (var element in journal) {
|
for (var element in journal) {
|
||||||
if (element.day == day) {
|
if (element.day == day) {
|
||||||
@@ -1323,14 +1489,11 @@ class UserOperations {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(exist){return;}
|
if (exist) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
String id = username + DateFormat('yyyy-MM-dd').format(day);
|
String id = username + DateFormat('yyyy-MM-dd').format(day);
|
||||||
Map<String, String> queryBody = <String, String>{
|
Map<String, String> queryBody = <String, String>{'username': username, 'id': id, 'title': title, 'description': text};
|
||||||
'username': username,
|
|
||||||
'id': id,
|
|
||||||
'title': title,
|
|
||||||
'description': text
|
|
||||||
};
|
|
||||||
if (cacheEnabled) {
|
if (cacheEnabled) {
|
||||||
//Add Query
|
//Add Query
|
||||||
Map<String, Object> query = {Queries.colLink: 'add_journal', Queries.colData: jsonEncode(queryBody)};
|
Map<String, Object> query = {Queries.colLink: 'add_journal', Queries.colData: jsonEncode(queryBody)};
|
||||||
@@ -1340,11 +1503,7 @@ class UserOperations {
|
|||||||
await cacheDb.insert('Queries', query);
|
await cacheDb.insert('Queries', query);
|
||||||
|
|
||||||
//update Cache
|
//update Cache
|
||||||
Map<String, Object> data = {
|
Map<String, Object> data = {'id': id, Journal.colTitle: title, Journal.colDescription: text};
|
||||||
'id':id,
|
|
||||||
Journal.colTitle: title,
|
|
||||||
Journal.colDescription:text
|
|
||||||
};
|
|
||||||
await cacheDb.insert('Journal', data);
|
await cacheDb.insert('Journal', data);
|
||||||
await refreshUserData(forceOffline: true);
|
await refreshUserData(forceOffline: true);
|
||||||
} else {
|
} else {
|
||||||
@@ -1361,18 +1520,12 @@ class UserOperations {
|
|||||||
}
|
}
|
||||||
//Add to server and refresh Cache
|
//Add to server and refresh Cache
|
||||||
await executeQueries();
|
await executeQueries();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<void> editJournal(DateTime oldDay, DateTime day, String title, String text) async {
|
static Future<void> editJournal(DateTime oldDay, DateTime day, String title, String text) async {
|
||||||
String oldId = username + DateFormat('yyyy-MM-dd').format(oldDay);
|
String oldId = username + DateFormat('yyyy-MM-dd').format(oldDay);
|
||||||
String id = username + DateFormat('yyyy-MM-dd').format(day);
|
String id = username + DateFormat('yyyy-MM-dd').format(day);
|
||||||
Map<String, String> queryBody = <String, String>{
|
Map<String, String> queryBody = <String, String>{'username': username, 'old_id': oldId, 'id': id, 'title': title, 'description': text};
|
||||||
'username': username,
|
|
||||||
'old_id':oldId,
|
|
||||||
'id': id,
|
|
||||||
'title': title,
|
|
||||||
'description': text
|
|
||||||
};
|
|
||||||
if (cacheEnabled) {
|
if (cacheEnabled) {
|
||||||
//Add Query
|
//Add Query
|
||||||
Map<String, Object> query = {Queries.colLink: 'edit_journal', Queries.colData: jsonEncode(queryBody)};
|
Map<String, Object> query = {Queries.colLink: 'edit_journal', Queries.colData: jsonEncode(queryBody)};
|
||||||
@@ -1380,13 +1533,10 @@ class UserOperations {
|
|||||||
print("adding new query ${query[Queries.colLink]} : ${jsonEncode(queryBody)}");
|
print("adding new query ${query[Queries.colLink]} : ${jsonEncode(queryBody)}");
|
||||||
|
|
||||||
await cacheDb.insert('Queries', query);
|
await cacheDb.insert('Queries', query);
|
||||||
await cacheDb.rawUpdate("UPDATE Journal SET id='$id', ${Journal.colTitle}='${title.toString().replaceAll("'", "''")}', ${Journal.colDescription}='${text.toString().replaceAll("'", "''")}' WHERE id='$oldId'");
|
await cacheDb.rawUpdate(
|
||||||
|
"UPDATE Journal SET id='$id', ${Journal.colTitle}='${title.toString().replaceAll("'", "''")}', ${Journal.colDescription}='${text.toString().replaceAll("'", "''")}' WHERE id='$oldId'");
|
||||||
//update Cache
|
//update Cache
|
||||||
Map<String, Object> data = {
|
Map<String, Object> data = {'id': id, Journal.colTitle: title, Journal.colDescription: text};
|
||||||
'id':id,
|
|
||||||
Journal.colTitle: title,
|
|
||||||
Journal.colDescription:text
|
|
||||||
};
|
|
||||||
// await cacheDb.insert('Journal', data);
|
// await cacheDb.insert('Journal', data);
|
||||||
await refreshUserData(forceOffline: true);
|
await refreshUserData(forceOffline: true);
|
||||||
} else {
|
} else {
|
||||||
@@ -1403,9 +1553,54 @@ class UserOperations {
|
|||||||
}
|
}
|
||||||
//Add to server and refresh Cache
|
//Add to server and refresh Cache
|
||||||
await executeQueries();
|
await executeQueries();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Future<void> addTodo(String taskType, String metadata, DateTime dueDate, DateTime? notificationTime) async {
|
||||||
|
|
||||||
|
String taskId = username + taskType;
|
||||||
|
if(taskId.contains('[') && taskId.contains(']')){
|
||||||
|
//has a project related
|
||||||
|
taskId = taskId.substring(0, taskId.indexOf('[') - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
String id = username + taskId + metadata;
|
||||||
|
|
||||||
|
Map<String, String> queryBody = <String, String>{
|
||||||
|
'username': username,
|
||||||
|
'task': taskId,
|
||||||
|
'metadata': metadata,
|
||||||
|
'due_date': DateFormat('yyyy-MM-dd').format(dueDate),
|
||||||
|
if(notificationTime!=null)'notification_time':DateFormat('yyyy-MM-dd HH:mm').format(notificationTime)
|
||||||
|
};
|
||||||
|
if (cacheEnabled) {
|
||||||
|
//Add Query
|
||||||
|
Map<String, Object> query = {Queries.colLink: 'add_todo', Queries.colData: jsonEncode(queryBody)};
|
||||||
|
|
||||||
|
print("adding new query ${query[Queries.colLink]} : ${jsonEncode(queryBody)}");
|
||||||
|
|
||||||
|
await cacheDb.insert('Queries', query);
|
||||||
|
|
||||||
|
//update Cache
|
||||||
|
Map<String, Object> data = {'id': id, Todo.colCat: username+taskType, Todo.colMetadata: metadata, Todo.colDueDate: DateFormat('yyyy-MM-dd').format(dueDate), if(notificationTime!=null)Todo.colNotificationTime:DateFormat('yyyy-MM-dd HH:mm').format(notificationTime)};
|
||||||
|
await cacheDb.insert('Todos', data);
|
||||||
|
await refreshUserData(forceOffline: true);
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
http.Response queryResponse = (await http.post(Uri.parse('http://161.97.127.136/task_tracker/add_todo.php'), body: queryBody));
|
||||||
|
print("Query executed : Results{${queryResponse.body}");
|
||||||
|
if (queryResponse.body.toLowerCase().contains("success")) {
|
||||||
|
//Success
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
print('NC: Error adding journal entry $e}');
|
||||||
|
}
|
||||||
|
//executeQueries();
|
||||||
|
}
|
||||||
|
//Add to server and refresh Cache
|
||||||
|
await executeQueries();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static Future<void> deleteTask(String name, {bulk = false}) async {
|
static Future<void> deleteTask(String name, {bulk = false}) async {
|
||||||
Map<String, String> queryBody = <String, String>{
|
Map<String, String> queryBody = <String, String>{
|
||||||
'id': username + name,
|
'id': username + name,
|
||||||
@@ -1534,8 +1729,7 @@ class UserOperations {
|
|||||||
await cacheDb.insert('Queries', query);
|
await cacheDb.insert('Queries', query);
|
||||||
|
|
||||||
//update Cache
|
//update Cache
|
||||||
String deleteQuery =
|
String deleteQuery = "DELETE FROM Projects WHERE ${Project.colName}='${username + project}'";
|
||||||
"DELETE FROM Projects WHERE ${Project.colName}='${username+project}'";
|
|
||||||
print("delteQuery : $deleteQuery");
|
print("delteQuery : $deleteQuery");
|
||||||
|
|
||||||
await cacheDb.rawDelete(deleteQuery);
|
await cacheDb.rawDelete(deleteQuery);
|
||||||
@@ -1571,8 +1765,7 @@ class UserOperations {
|
|||||||
await cacheDb.insert('Queries', query);
|
await cacheDb.insert('Queries', query);
|
||||||
|
|
||||||
//update Cache
|
//update Cache
|
||||||
String deleteQuery =
|
String deleteQuery = "DELETE FROM Journal WHERE id='$id'";
|
||||||
"DELETE FROM Journal WHERE id='$id'";
|
|
||||||
print("delteQuery : $deleteQuery");
|
print("delteQuery : $deleteQuery");
|
||||||
|
|
||||||
await cacheDb.rawDelete(deleteQuery);
|
await cacheDb.rawDelete(deleteQuery);
|
||||||
@@ -1617,7 +1810,7 @@ class UserOperations {
|
|||||||
try {
|
try {
|
||||||
http.Response queryResponse = (await http.post(Uri.parse('http://161.97.127.136/task_tracker/$file.php'), body: body));
|
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}");
|
print("Query executed : Results{${queryResponse.body}");
|
||||||
if (queryResponse.body.toLowerCase().contains("success")) {
|
if (queryResponse.body.toLowerCase().contains("+")) {
|
||||||
await cacheDb.rawDelete('DELETE FROM Queries WHERE id=$id');
|
await cacheDb.rawDelete('DELETE FROM Queries WHERE id=$id');
|
||||||
}
|
}
|
||||||
offline = false;
|
offline = false;
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import 'package:shared_preferences/shared_preferences.dart';
|
|||||||
import 'package:tasktracker/Categories.dart';
|
import 'package:tasktracker/Categories.dart';
|
||||||
import 'package:tasktracker/Journal.dart';
|
import 'package:tasktracker/Journal.dart';
|
||||||
import 'package:tasktracker/Projects.dart';
|
import 'package:tasktracker/Projects.dart';
|
||||||
import 'package:tasktracker/Todo.dart';
|
import 'package:tasktracker/Todos.dart';
|
||||||
import 'package:tasktracker/Welcome.dart';
|
import 'package:tasktracker/Welcome.dart';
|
||||||
import 'package:tasktracker/splash.dart';
|
import 'package:tasktracker/splash.dart';
|
||||||
import 'package:tasktracker/theme_provider.dart';
|
import 'package:tasktracker/theme_provider.dart';
|
||||||
@@ -113,7 +113,8 @@ class MyApp extends StatelessWidget {
|
|||||||
'/Activities': (context) => const Activities(),
|
'/Activities': (context) => const Activities(),
|
||||||
'/Settings': (context) => const SettingsPage(),
|
'/Settings': (context) => const SettingsPage(),
|
||||||
'/Projects':(context)=> const Projects(),
|
'/Projects':(context)=> const Projects(),
|
||||||
'/Journal': (context)=> const JournalPage()
|
'/Journal': (context)=> const JournalPage(),
|
||||||
|
'/Todos':(context)=> const TodosPage()
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -205,7 +206,7 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||||||
// }
|
// }
|
||||||
hourglassTime = ((DateTime.now().hour * 60) + DateTime.now().minute) / 1440;
|
hourglassTime = ((DateTime.now().hour * 60) + DateTime.now().minute) / 1440;
|
||||||
// hourglassTime = 1;
|
// hourglassTime = 1;
|
||||||
print('hourglass time : $hourglassTime');
|
// print('hourglass time : $hourglassTime');
|
||||||
hourglassColors =[];
|
hourglassColors =[];
|
||||||
hourglassStops = [];
|
hourglassStops = [];
|
||||||
hourglassTotalTime=0;
|
hourglassTotalTime=0;
|
||||||
@@ -214,11 +215,11 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||||||
hourglassTotalTime+=element.time;
|
hourglassTotalTime+=element.time;
|
||||||
// }
|
// }
|
||||||
});
|
});
|
||||||
print('hourglass cat data');
|
// print('hourglass cat data');
|
||||||
double stopsTotal = 0;
|
double stopsTotal = 0;
|
||||||
for(int i =0 ; i < hourglassCatData.length; i++) {
|
for(int i =0 ; i < hourglassCatData.length; i++) {
|
||||||
CatMapData element = hourglassCatData[i];
|
CatMapData element = hourglassCatData[i];
|
||||||
print('${element.name} : ${element.time} / $hourglassTotalTime = ${element.time / hourglassTotalTime}');
|
// print('${element.name} : ${element.time} / $hourglassTotalTime = ${element.time / hourglassTotalTime}');
|
||||||
double thisStop = ( element.time/hourglassTotalTime);
|
double thisStop = ( element.time/hourglassTotalTime);
|
||||||
hourglassColors.add(element.color);
|
hourglassColors.add(element.color);
|
||||||
hourglassStops.add(stopsTotal+thisStop);
|
hourglassStops.add(stopsTotal+thisStop);
|
||||||
@@ -228,14 +229,14 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||||||
hourglassStops.add(stopsTotal+thisStop + 0.001);
|
hourglassStops.add(stopsTotal+thisStop + 0.001);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
print('total Stops ${stopsTotal}');
|
// print('total Stops ${stopsTotal}');
|
||||||
print('maxT: $hourglassTotalTime');
|
// print('maxT: $hourglassTotalTime');
|
||||||
if(hourglassColors.isEmpty){
|
if(hourglassColors.isEmpty){
|
||||||
hourglassColors.add(Colors.black);
|
hourglassColors.add(Colors.black);
|
||||||
hourglassStops.add(1);
|
hourglassStops.add(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
print('hourglass \n$hourglassColors \n$hourglassStops');
|
// print('hourglass \n$hourglassColors \n$hourglassStops');
|
||||||
setState(() {
|
setState(() {
|
||||||
|
|
||||||
});
|
});
|
||||||
@@ -292,6 +293,7 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool loadingStats = false;
|
bool loadingStats = false;
|
||||||
|
DateFormat dFormat = DateFormat("yyyy-MM-dd");
|
||||||
void LoadStats() async {
|
void LoadStats() async {
|
||||||
// return;
|
// return;
|
||||||
// await User.refreshUserData();
|
// await User.refreshUserData();
|
||||||
@@ -304,7 +306,7 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||||||
}
|
}
|
||||||
await Refresh();
|
await Refresh();
|
||||||
|
|
||||||
DateFormat dFormat = DateFormat("MM/dd");
|
|
||||||
Map<Category, int> catTimeMap = <Category, int>{};
|
Map<Category, int> catTimeMap = <Category, int>{};
|
||||||
Map<Category, int> catBriefMap = <Category, int>{};
|
Map<Category, int> catBriefMap = <Category, int>{};
|
||||||
|
|
||||||
@@ -354,13 +356,16 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||||||
taskTypesDuration.putIfAbsent(element.taskType, () => thisMinutes);
|
taskTypesDuration.putIfAbsent(element.taskType, () => thisMinutes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((element.startTime.isAfter(prodRange!.start) && element.startTime.isBefore(prodRange!.end)) ||
|
|
||||||
(dFormat.format(element.startTime) == dFormat.format(prodRange!.start) || dFormat.format(element.startTime) == dFormat.format(prodRange!.end))) {
|
|
||||||
if (element.taskType.cat?.productive ?? false) {
|
if (element.taskType.cat?.productive ?? false) {
|
||||||
if (lastProductive == null) {
|
if (lastProductive == null) {
|
||||||
lastProductive = element.trueEndTime;
|
lastProductive = element.trueEndTime;
|
||||||
}
|
}}
|
||||||
|
if ((element.startTime.isAfter(prodRange!.start) && element.startTime.isBefore(prodRange!.end)) ||
|
||||||
|
(dFormat.format(element.startTime) == dFormat.format(prodRange!.start) || dFormat.format(element.startTime) == dFormat.format(prodRange!.end))) {
|
||||||
|
if (element.taskType.cat?.productive ?? false) {
|
||||||
|
// if (lastProductive == null) {
|
||||||
|
// lastProductive = element.trueEndTime;
|
||||||
|
// }
|
||||||
if (productivtyActs.containsKey(thisDate)) {
|
if (productivtyActs.containsKey(thisDate)) {
|
||||||
productivtyActs[thisDate] = (productivtyActs[thisDate]! + thisMinutes);
|
productivtyActs[thisDate] = (productivtyActs[thisDate]! + thisMinutes);
|
||||||
} else {
|
} else {
|
||||||
@@ -728,15 +733,19 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||||||
series: <LineSeries<ProductivityMapData, String>>[
|
series: <LineSeries<ProductivityMapData, String>>[
|
||||||
LineSeries<ProductivityMapData, String>(
|
LineSeries<ProductivityMapData, String>(
|
||||||
// Bind data source
|
// Bind data source
|
||||||
|
markerSettings: MarkerSettings(isVisible: true, shape: DataMarkerType.circle),
|
||||||
dataSource: productivityData.reversed.toList(),
|
dataSource: productivityData.reversed.toList(),
|
||||||
xValueMapper: (ProductivityMapData sales, _) => sales.day,
|
xValueMapper: (ProductivityMapData sales, _) => DateFormat('MM-dd').format(dFormat.parse(sales.day)),
|
||||||
yValueMapper: (ProductivityMapData sales, _) => sales.productivity,
|
yValueMapper: (ProductivityMapData sales, _) => sales.productivity,
|
||||||
dataLabelMapper: (ProductivityMapData sales, _) => sales.productivity.toStringAsFixed(1) + "%",
|
dataLabelMapper: (ProductivityMapData sales, _) => sales.productivity.toStringAsFixed(1) + "%",
|
||||||
dataLabelSettings: DataLabelSettings(overflowMode: OverflowMode.hide, showZeroValue: false, isVisible: true),
|
dataLabelSettings: DataLabelSettings(overflowMode: OverflowMode.hide, showZeroValue: false, isVisible: true),
|
||||||
onPointTap: (ChartPointDetails point){
|
onPointTap: (ChartPointDetails point){
|
||||||
showAlertDialog(context, productivityData[point.pointIndex!].day, "I'll show you detailed info about this day in future, When my master creates the feature");
|
Dialogs.showJournalLink(dFormat.parse(productivityData[productivityData.length-point.pointIndex!-1].day));
|
||||||
|
//showAlertDialog(context, productivityData[point.pointIndex!].day, "I'll show you detailed info about this day in future, When my master creates the feature");
|
||||||
},
|
},
|
||||||
color: Colors.green)
|
pointColorMapper: (ProductivityMapData sales, _)=> (User.journalExists(dFormat.parse(sales.day)) ? Colors.lightGreenAccent : Colors.green)
|
||||||
|
)
|
||||||
|
//color: User.journalExists(dFormat.parse(productivityData[(productivityData.length-point.pointIndex!-1) as int].day)) ?Colors.green : Colors.red,
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
SizedBox(height: 20,),
|
SizedBox(height: 20,),
|
||||||
@@ -778,7 +787,6 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||||||
child: SfCircularChart(legend: Legend(isVisible: true,position: LegendPosition.bottom,overflowMode: LegendItemOverflowMode.wrap), series: <CircularSeries>[
|
child: SfCircularChart(legend: Legend(isVisible: true,position: LegendPosition.bottom,overflowMode: LegendItemOverflowMode.wrap), series: <CircularSeries>[
|
||||||
// Render pie chart
|
// Render pie chart
|
||||||
PieSeries<CatMapData, String>(
|
PieSeries<CatMapData, String>(
|
||||||
|
|
||||||
dataSource: dailyData,
|
dataSource: dailyData,
|
||||||
pointColorMapper: (CatMapData data, _) => data.color,
|
pointColorMapper: (CatMapData data, _) => data.color,
|
||||||
xValueMapper: (CatMapData data, _) => data.name,
|
xValueMapper: (CatMapData data, _) => data.name,
|
||||||
@@ -1013,6 +1021,17 @@ Drawer navDrawer(BuildContext context, int pageIndex) {
|
|||||||
Navigator.of(context).pushReplacementNamed('/Projects');
|
Navigator.of(context).pushReplacementNamed('/Projects');
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
ListTile(
|
||||||
|
selected: (pageIndex == 9),
|
||||||
|
title: Text('To-Do'),
|
||||||
|
leading: FaIcon(FontAwesomeIcons.calendarCheck, color: Theme.of(context).primaryColor),
|
||||||
|
onTap: () {
|
||||||
|
if (pageIndex == 9) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Navigator.of(context).pushReplacementNamed('/Todos');
|
||||||
|
},
|
||||||
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
selected: (pageIndex == 8),
|
selected: (pageIndex == 8),
|
||||||
title: Text('Journal'),
|
title: Text('Journal'),
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ import 'package:tasktracker/NotificationsManager.dart';
|
|||||||
import 'package:tasktracker/main.dart';
|
import 'package:tasktracker/main.dart';
|
||||||
import 'Data.dart';
|
import 'Data.dart';
|
||||||
import 'User.dart' as User;
|
import 'User.dart' as User;
|
||||||
DateFormat dateFormat = DateFormat("yyyy-MM-dd HH:mm:ss");
|
|
||||||
|
DateFormat dateTimeFormat = DateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
DateFormat durationFormat = DateFormat("HH:mm:ss");
|
DateFormat durationFormat = DateFormat("HH:mm:ss");
|
||||||
|
|
||||||
class NewActivity extends StatefulWidget {
|
class NewActivity extends StatefulWidget {
|
||||||
@@ -20,8 +21,6 @@ class NewActivity extends StatefulWidget {
|
|||||||
_NewActivity createState() => _NewActivity(eTime: eTime, sTime: sTime, selectedCat: selectedTask, metadata: metadata);
|
_NewActivity createState() => _NewActivity(eTime: eTime, sTime: sTime, selectedCat: selectedTask, metadata: metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class _NewActivity extends State<NewActivity> {
|
class _NewActivity extends State<NewActivity> {
|
||||||
late DateTime init_sTime;
|
late DateTime init_sTime;
|
||||||
late DateTime init_eTime;
|
late DateTime init_eTime;
|
||||||
@@ -32,9 +31,14 @@ class _NewActivity extends State<NewActivity> {
|
|||||||
this.init_sTime = this.startTime = sTime ?? DateTime.now();
|
this.init_sTime = this.startTime = sTime ?? DateTime.now();
|
||||||
this.init_eTime = this.endTime = eTime ?? DateTime.now().add(Duration(minutes: 30));
|
this.init_eTime = this.endTime = eTime ?? DateTime.now().add(Duration(minutes: 30));
|
||||||
this.metadataController.text = metadata ?? "";
|
this.metadataController.text = metadata ?? "";
|
||||||
|
if(this.metadataController.text.contains('[') && this.metadataController.text.contains(']') ){
|
||||||
|
this.metadataController.text = this.metadataController.text.substring(this.metadataController.text.indexOf(']')+1);
|
||||||
|
selectedStep = metadata!.substring(1,metadata!.indexOf(']'));
|
||||||
|
}else{
|
||||||
|
selectedStep='None';
|
||||||
|
}
|
||||||
this.init_selectedTask = this.selectedCat = selectedCat ?? User.taskTypes[0].name;
|
this.init_selectedTask = this.selectedCat = selectedCat ?? User.taskTypes[0].name;
|
||||||
print("etime:$eTime, sTime:$sTime, meta:$metadata, task: $selectedCat");
|
print("etime:$eTime, sTime:$sTime, meta:$metadata, task: $selectedCat");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
late DateTime startTime;
|
late DateTime startTime;
|
||||||
@@ -42,56 +46,74 @@ class _NewActivity extends State<NewActivity> {
|
|||||||
TextEditingController metadataController = TextEditingController();
|
TextEditingController metadataController = TextEditingController();
|
||||||
late String selectedCat;
|
late String selectedCat;
|
||||||
|
|
||||||
|
|
||||||
bool editing = false;
|
bool editing = false;
|
||||||
|
Map<String, TaskType?> taskTypes = <String, TaskType?>{};
|
||||||
List<String> getActivities(){
|
Map<String, TaskType?> getActivities() {
|
||||||
List<String> _cats = [];
|
Map<String, TaskType?> _cats = <String, TaskType?>{};
|
||||||
_cats.add("+Add New Task Type");
|
_cats.putIfAbsent("+Add New Task Type", () => null);
|
||||||
if (User.taskTypes.isEmpty) {
|
if (User.taskTypes.isEmpty) {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
print(User.taskTypes[0].name + " : " + selectedCat);
|
print(User.taskTypes[0].name + " : " + selectedCat);
|
||||||
}
|
}
|
||||||
User.taskTypes.forEach((element) {
|
User.taskTypes.forEach((element) {
|
||||||
String name = element.name;
|
String name = element.name;
|
||||||
if(_cats.contains(element.name)){
|
if (_cats.keys.toString().contains(element.name)) {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
_cats.add(name + ((element.relatedProject !=null) ? ' [${element.relatedProject!.name}]' :''));
|
String displayName = (name + ((element.relatedProject != null) ? ' [${element.relatedProject!.name}]' : ''));
|
||||||
|
_cats.putIfAbsent(displayName, () => element);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return _cats;
|
return _cats;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String? selectedStep = null;
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
taskTypes = getActivities();
|
||||||
|
bool canSelectStep = false;
|
||||||
|
List<String> steps = ['None'];
|
||||||
|
if (taskTypes[selectedCat] != null) {
|
||||||
|
if (taskTypes[selectedCat]!.relatedProject != null) {
|
||||||
|
//Got a project. But is it multi step?
|
||||||
|
if (taskTypes[selectedCat]!.relatedProject!.steps.isNotEmpty) {
|
||||||
|
canSelectStep = true;
|
||||||
|
bool matchesSelectedStep = false;
|
||||||
|
taskTypes[selectedCat]!.relatedProject!.steps.forEach((element) {
|
||||||
|
if (element.finishedDate == null) {
|
||||||
|
steps.add(element.stepName);
|
||||||
|
if (selectedStep == null) {
|
||||||
|
selectedStep = element.stepName;
|
||||||
|
matchesSelectedStep = true;
|
||||||
|
}
|
||||||
|
if (element.stepName == selectedStep) {
|
||||||
|
matchesSelectedStep = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (!matchesSelectedStep) {
|
||||||
|
selectedStep = steps[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(title: Text((editing) ? 'Edit Activity' : 'New Activity')),
|
appBar: AppBar(title: Text((editing) ? 'Edit Activity' : 'New Activity')),
|
||||||
body:Column(
|
body: Column(mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
|
||||||
mainAxisSize: MainAxisSize.max,
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
Expanded(
|
Expanded(
|
||||||
flex: 9,
|
flex: 9,
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
scrollDirection: Axis.vertical,
|
scrollDirection: Axis.vertical,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: EdgeInsets.fromLTRB(20, 50, 20, 50),
|
padding: EdgeInsets.fromLTRB(20, 10, 20, 10),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
Column(children: [
|
Column(children: [
|
||||||
|
Container(padding: EdgeInsets.all(10), child: Text('Task')),
|
||||||
Container(
|
Container(
|
||||||
padding: EdgeInsets.all(10),
|
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 1),
|
||||||
child: Text('Task')),
|
|
||||||
|
|
||||||
Container(
|
|
||||||
padding: EdgeInsets.symmetric(
|
|
||||||
horizontal: 12, vertical: 1),
|
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.black12,
|
color: Colors.black12, borderRadius: BorderRadius.circular(12), border: Border.all(color: Colors.grey, width: 2)),
|
||||||
borderRadius: BorderRadius.circular(12),
|
|
||||||
border: Border.all(
|
|
||||||
color: Colors.grey, width: 2)),
|
|
||||||
child: DropdownButton<String>(
|
child: DropdownButton<String>(
|
||||||
dropdownColor: Color(0xFF222222),
|
dropdownColor: Color(0xFF222222),
|
||||||
iconSize: 30,
|
iconSize: 30,
|
||||||
@@ -99,8 +121,7 @@ class _NewActivity extends State<NewActivity> {
|
|||||||
borderRadius: BorderRadius.circular(10),
|
borderRadius: BorderRadius.circular(10),
|
||||||
value: selectedCat,
|
value: selectedCat,
|
||||||
isExpanded: true,
|
isExpanded: true,
|
||||||
items: getActivities().map<DropdownMenuItem<String>>(
|
items: getActivities().keys.map<DropdownMenuItem<String>>((String value) {
|
||||||
(String value) {
|
|
||||||
print(value);
|
print(value);
|
||||||
return DropdownMenuItem<String>(
|
return DropdownMenuItem<String>(
|
||||||
value: value,
|
value: value,
|
||||||
@@ -109,43 +130,56 @@ class _NewActivity extends State<NewActivity> {
|
|||||||
}).toList(),
|
}).toList(),
|
||||||
onChanged: (String? _value) {
|
onChanged: (String? _value) {
|
||||||
if (_value == '+Add New Task Type') {
|
if (_value == '+Add New Task Type') {
|
||||||
Navigator.of(context).push(MaterialPageRoute(builder: (context)=> NewTask())).then((val){setState(() {
|
Navigator.of(context).push(MaterialPageRoute(builder: (context) => NewTask())).then((val) {
|
||||||
|
setState(() {});
|
||||||
});});
|
|
||||||
}else{
|
|
||||||
|
|
||||||
selectedCat = _value ?? 'n/a';
|
|
||||||
|
|
||||||
}
|
|
||||||
setState(() {
|
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
selectedCat = _value ?? 'n/a';
|
||||||
|
}
|
||||||
|
setState(() {});
|
||||||
|
})),
|
||||||
|
if (canSelectStep) Container(padding: EdgeInsets.all(10), child: Text('Step')),
|
||||||
|
if (canSelectStep)
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 1),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.black12, borderRadius: BorderRadius.circular(12), border: Border.all(color: Colors.grey, width: 2)),
|
||||||
|
child: DropdownButton<String>(
|
||||||
|
dropdownColor: Color(0xFF222222),
|
||||||
|
iconSize: 30,
|
||||||
|
elevation: 10,
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
value: selectedStep,
|
||||||
|
isExpanded: true,
|
||||||
|
items: steps.map<DropdownMenuItem<String>>((String value) {
|
||||||
|
print(value);
|
||||||
|
return DropdownMenuItem<String>(
|
||||||
|
value: value,
|
||||||
|
child: Text(value),
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
onChanged: (String? _value) {
|
||||||
|
selectedStep = _value;
|
||||||
|
setState(() {});
|
||||||
})),
|
})),
|
||||||
|
|
||||||
Container(
|
Container(
|
||||||
padding: EdgeInsets.all(10),
|
padding: EdgeInsets.all(10),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
|
|
||||||
TextField(
|
TextField(
|
||||||
controller: metadataController,
|
controller: metadataController,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText: 'Description (optional)',
|
hintText: 'Description (optional)',
|
||||||
filled: true,
|
filled: true,
|
||||||
border: OutlineInputBorder(
|
border: OutlineInputBorder(borderRadius: BorderRadius.circular(20))),
|
||||||
borderRadius: BorderRadius.circular(20)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
)
|
)),
|
||||||
),
|
|
||||||
Container(
|
Container(
|
||||||
child: Divider(
|
child: Divider(
|
||||||
height: 30,
|
height: 30,
|
||||||
)),
|
)),
|
||||||
Container(
|
Container(padding: EdgeInsets.all(10), child: Text('Start Time')),
|
||||||
padding: EdgeInsets.all(10),
|
|
||||||
child: Text('Start Time')),
|
|
||||||
Row(
|
Row(
|
||||||
mainAxisSize: MainAxisSize.max,
|
mainAxisSize: MainAxisSize.max,
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
@@ -154,23 +188,14 @@ class _NewActivity extends State<NewActivity> {
|
|||||||
if (User.activities.length > 0) {
|
if (User.activities.length > 0) {
|
||||||
startTime = User.activities[0].endTime;
|
startTime = User.activities[0].endTime;
|
||||||
}
|
}
|
||||||
})
|
}),
|
||||||
,
|
|
||||||
Container(
|
Container(
|
||||||
padding: EdgeInsets.symmetric(
|
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 1),
|
||||||
horizontal: 12, vertical: 1),
|
decoration: BoxDecoration(borderRadius: BorderRadius.circular(12), border: Border.all(color: Colors.grey, width: 2)),
|
||||||
decoration: BoxDecoration(
|
|
||||||
borderRadius: BorderRadius.circular(12),
|
|
||||||
border: Border.all(
|
|
||||||
color: Colors.grey, width: 2)),
|
|
||||||
child: MaterialButton(
|
child: MaterialButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
DatePicker.showDateTimePicker(
|
DatePicker.showDateTimePicker(context, maxTime: endTime, showTitleActions: true, onChanged: (date) {
|
||||||
context,
|
|
||||||
maxTime: endTime,
|
|
||||||
showTitleActions: true,
|
|
||||||
onChanged: (date) {
|
|
||||||
// print('change $date');
|
// print('change $date');
|
||||||
}, onConfirm: (date) {
|
}, onConfirm: (date) {
|
||||||
setState(() {
|
setState(() {
|
||||||
@@ -183,15 +208,10 @@ class _NewActivity extends State<NewActivity> {
|
|||||||
startTime = date;
|
startTime = date;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
}, currentTime: startTime, locale: LocaleType.en);
|
||||||
currentTime: startTime,
|
|
||||||
locale: LocaleType.en);
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(dateTimeFormat.format(startTime), style: TextStyle(color: Colors.blue)))),
|
||||||
dateFormat.format(startTime),
|
|
||||||
style: TextStyle(
|
|
||||||
color: Colors.blue)))),
|
|
||||||
QuickTimeButton('Now', Function: () {
|
QuickTimeButton('Now', Function: () {
|
||||||
startTime = DateTime.now();
|
startTime = DateTime.now();
|
||||||
})
|
})
|
||||||
@@ -200,31 +220,21 @@ class _NewActivity extends State<NewActivity> {
|
|||||||
SizedBox(
|
SizedBox(
|
||||||
height: 10,
|
height: 10,
|
||||||
),
|
),
|
||||||
Container(
|
Container(padding: EdgeInsets.all(10), child: Text('Ended Time')),
|
||||||
padding: EdgeInsets.all(10),
|
|
||||||
child: Text('Ended Time')),
|
|
||||||
|
|
||||||
Row(
|
Row(
|
||||||
mainAxisSize: MainAxisSize.max,
|
mainAxisSize: MainAxisSize.max,
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
children: [
|
children: [
|
||||||
Container(width: 60,),
|
|
||||||
Container(
|
Container(
|
||||||
padding: EdgeInsets.symmetric(
|
width: 60,
|
||||||
horizontal: 12, vertical: 1),
|
),
|
||||||
decoration: BoxDecoration(
|
Container(
|
||||||
borderRadius: BorderRadius.circular(12),
|
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 1),
|
||||||
border: Border.all(
|
decoration: BoxDecoration(borderRadius: BorderRadius.circular(12), border: Border.all(color: Colors.grey, width: 2)),
|
||||||
color: Colors.grey, width: 2)),
|
|
||||||
child: MaterialButton(
|
child: MaterialButton(
|
||||||
|
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
DatePicker.showDateTimePicker(
|
DatePicker.showDateTimePicker(context, showTitleActions: true, minTime: startTime, onChanged: (date) {
|
||||||
context,
|
|
||||||
showTitleActions: true,
|
|
||||||
minTime: startTime,
|
|
||||||
onChanged: (date) {
|
|
||||||
// print('change $date');
|
// print('change $date');
|
||||||
}, onConfirm: (date) {
|
}, onConfirm: (date) {
|
||||||
setState(() {
|
setState(() {
|
||||||
@@ -237,30 +247,27 @@ class _NewActivity extends State<NewActivity> {
|
|||||||
endTime = date;
|
endTime = date;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
}, currentTime: endTime, locale: LocaleType.en);
|
||||||
currentTime: endTime,
|
|
||||||
locale: LocaleType.en);
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
child: Text(dateFormat.format(endTime),
|
child: Text(dateTimeFormat.format(endTime), style: TextStyle(color: Colors.blue)))),
|
||||||
style: TextStyle(
|
|
||||||
color: Colors.blue)))),
|
|
||||||
QuickTimeButton('Now', Function: () {
|
QuickTimeButton('Now', Function: () {
|
||||||
endTime = DateTime.now();
|
endTime = DateTime.now();
|
||||||
})
|
})
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
SizedBox(height: 15,),
|
SizedBox(
|
||||||
(!editing)?Container(
|
height: 15,
|
||||||
|
),
|
||||||
|
(!editing)
|
||||||
|
? Container(
|
||||||
child: Card(
|
child: Card(
|
||||||
shadowColor: Colors.blue,
|
shadowColor: Colors.blue,
|
||||||
elevation: 20,
|
elevation: 20,
|
||||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
|
||||||
// color: Color(0xAA51AAFF),
|
// color: Color(0xAA51AAFF),
|
||||||
color: Colors.deepPurpleAccent,
|
color: Colors.deepPurpleAccent,
|
||||||
child: Column(
|
child: Column(mainAxisSize: MainAxisSize.max, children: [
|
||||||
mainAxisSize: MainAxisSize.max,
|
|
||||||
children:[
|
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
child: Row(
|
child: Row(
|
||||||
@@ -269,14 +276,18 @@ class _NewActivity extends State<NewActivity> {
|
|||||||
children: [
|
children: [
|
||||||
Icon(Icons.lightbulb, color: Colors.yellowAccent),
|
Icon(Icons.lightbulb, color: Colors.yellowAccent),
|
||||||
Text('Not finished yet?', style: TextStyle(fontSize: 18)),
|
Text('Not finished yet?', style: TextStyle(fontSize: 18)),
|
||||||
Container(width: 15,),
|
Container(
|
||||||
|
width: 15,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
child: Text('Click following button to start tracking an unfinished Activity. Activity will be added when you finish it.', textAlign: TextAlign.center,),
|
child: Text(
|
||||||
|
'Click following button to start tracking an unfinished Activity. Activity will be added when you finish it.',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
@@ -293,23 +304,22 @@ class _NewActivity extends State<NewActivity> {
|
|||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
Icon(Icons.access_time),
|
Icon(Icons.access_time),
|
||||||
SizedBox(width: 10,),
|
SizedBox(
|
||||||
|
width: 10,
|
||||||
|
),
|
||||||
Text('Start Timer'),
|
Text('Start Timer'),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
]
|
])),
|
||||||
)
|
)
|
||||||
),
|
: Container(),
|
||||||
) : Container(),
|
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 30,
|
height: 30,
|
||||||
),
|
),
|
||||||
Text('Duration : ' +
|
Text('Duration : ' + _printDuration(endTime.difference(startTime)),
|
||||||
_printDuration(
|
|
||||||
endTime.difference(startTime)),
|
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
)),
|
)),
|
||||||
@@ -318,22 +328,17 @@ class _NewActivity extends State<NewActivity> {
|
|||||||
),
|
),
|
||||||
Column(
|
Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [],
|
||||||
|
|
||||||
],
|
|
||||||
)
|
)
|
||||||
]),
|
]),
|
||||||
|
|
||||||
],
|
],
|
||||||
|
|
||||||
)),
|
)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
flex: 1,
|
flex: 1,
|
||||||
child: Container(
|
child: Container(
|
||||||
padding:
|
padding: EdgeInsets.symmetric(vertical: 10, horizontal: 20),
|
||||||
EdgeInsets.symmetric(vertical: 10, horizontal: 20),
|
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisSize: MainAxisSize.max,
|
mainAxisSize: MainAxisSize.max,
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
@@ -343,25 +348,17 @@ class _NewActivity extends State<NewActivity> {
|
|||||||
child: Container(
|
child: Container(
|
||||||
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 0),
|
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 0),
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
|
style: ElevatedButton.styleFrom(primary: Colors.red, shape: StadiumBorder()),
|
||||||
style:ElevatedButton.styleFrom(
|
|
||||||
primary: Colors.red,
|
|
||||||
shape: StadiumBorder()
|
|
||||||
),
|
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
},
|
},
|
||||||
child: Text('Back',
|
child: Text('Back', style: TextStyle(fontSize: 20))))),
|
||||||
style: TextStyle(fontSize: 20))))),
|
|
||||||
Expanded(
|
Expanded(
|
||||||
flex: 6,
|
flex: 6,
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 0),
|
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 0),
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
style:ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(primary: Colors.green, shape: StadiumBorder()),
|
||||||
primary: Colors.green,
|
|
||||||
shape: StadiumBorder()
|
|
||||||
),
|
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
if (editing) {
|
if (editing) {
|
||||||
edit_action();
|
edit_action();
|
||||||
@@ -369,8 +366,7 @@ class _NewActivity extends State<NewActivity> {
|
|||||||
add_action();
|
add_action();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: Text((editing) ? 'Apply':'Add Activity',
|
child: Text((editing) ? 'Apply' : 'Add Activity', style: TextStyle(fontSize: 20))))),
|
||||||
style: TextStyle(fontSize: 20))))),
|
|
||||||
],
|
],
|
||||||
)),
|
)),
|
||||||
)
|
)
|
||||||
@@ -382,19 +378,16 @@ class _NewActivity extends State<NewActivity> {
|
|||||||
child: Container(
|
child: Container(
|
||||||
padding: EdgeInsets.symmetric(horizontal: 15),
|
padding: EdgeInsets.symmetric(horizontal: 15),
|
||||||
height: 30,
|
height: 30,
|
||||||
decoration:BoxDecoration(
|
decoration: BoxDecoration(color: Colors.blueAccent, borderRadius: BorderRadius.circular(50)),
|
||||||
color: Colors.blueAccent,
|
child: Align(
|
||||||
borderRadius: BorderRadius.circular(50)
|
child: Text(text),
|
||||||
),
|
alignment: Alignment.center,
|
||||||
child:Align(child: Text(text),alignment: Alignment.center,)
|
)),
|
||||||
),
|
|
||||||
|
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Function();
|
Function();
|
||||||
setState(() {
|
setState(() {});
|
||||||
|
},
|
||||||
});
|
);
|
||||||
},);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_action() async {
|
void add_action() async {
|
||||||
@@ -408,8 +401,9 @@ class _NewActivity extends State<NewActivity> {
|
|||||||
}
|
}
|
||||||
print('adding Task Type : $selectedTasks at $startTime - $endTime');
|
print('adding Task Type : $selectedTasks at $startTime - $endTime');
|
||||||
bool failed = false;
|
bool failed = false;
|
||||||
await User.UserOperations.addActivity(selectedTasks,startTime, endTime,metadata:metadataController.text, onOverlap: (overlapCount){
|
await User.UserOperations.addActivity(selectedTasks, startTime, endTime, metadata:((selectedStep!=null && selectedStep != 'None') ? '[$selectedStep]' : '')+ metadataController.text, 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');
|
showAlertDialog(context, 'Error adding activity',
|
||||||
|
'Cannot add activity between ${dateTimeFormat.format(startTime)} - ${dateTimeFormat.format(endTime)}, $overlapCount activities are already added within this time range');
|
||||||
failed = true;
|
failed = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -431,8 +425,10 @@ class _NewActivity extends State<NewActivity> {
|
|||||||
}
|
}
|
||||||
print('adding Task Type : $selectedTasks at $startTime - $endTime');
|
print('adding Task Type : $selectedTasks at $startTime - $endTime');
|
||||||
bool failed = false;
|
bool failed = false;
|
||||||
await User.UserOperations.editActivity(init_sTime,init_eTime,selectedTasks,startTime, endTime,metadata:metadataController.text, onOverlap: (overlapCount){
|
await User.UserOperations.editActivity(init_sTime, init_eTime, selectedTasks, startTime, endTime,metadata: ((selectedStep!=null && selectedStep != 'None') ? '[$selectedStep]' : '')+ metadataController.text,
|
||||||
showAlertDialog(context, 'Error editing activity', 'Cannot add activity between ${dateFormat.format(startTime)} - ${dateFormat.format(endTime)}, $overlapCount activities are already added within this time range');
|
onOverlap: (overlapCount) {
|
||||||
|
showAlertDialog(context, 'Error editing activity',
|
||||||
|
'Cannot add activity between ${dateTimeFormat.format(startTime)} - ${dateTimeFormat.format(endTime)}, $overlapCount activities are already added within this time range');
|
||||||
failed = true;
|
failed = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -455,11 +451,12 @@ String _printDuration(Duration duration) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
showAlertDialog(BuildContext context, String title, String message) {
|
showAlertDialog(BuildContext context, String title, String message) {
|
||||||
|
|
||||||
// set up the button
|
// set up the button
|
||||||
Widget okButton = TextButton(
|
Widget okButton = TextButton(
|
||||||
child: Text("OK"),
|
child: Text("OK"),
|
||||||
onPressed: () { Navigator.of(context).pop(); },
|
onPressed: () {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
// set up the AlertDialog
|
// set up the AlertDialog
|
||||||
|
|||||||
Reference in New Issue
Block a user