Hourglass improved + projects delete
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
import 'dart:math';
|
||||
import 'dart:ui' as ui;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/painting.dart';
|
||||
|
||||
class HourglassPainter extends CustomPainter{
|
||||
double fillAmount =0;
|
||||
@@ -29,6 +30,12 @@ class HourglassPainter extends CustomPainter{
|
||||
..strokeWidth=5
|
||||
// ..shader=ui.Gradient.linear(Offset(0,0), Offset(100,100), [Colors.green, Colors.amber, Colors.blue])
|
||||
..style=PaintingStyle.stroke;
|
||||
final outlinePainter2 = Paint()
|
||||
..color=Colors.amber
|
||||
..strokeCap=StrokeCap.round
|
||||
..strokeWidth=8
|
||||
// ..shader=ui.Gradient.linear(Offset(0,0), Offset(100,100), [Colors.green, Colors.amber, Colors.blue])
|
||||
..style=PaintingStyle.stroke;
|
||||
final contentPainter = Paint()
|
||||
..color=Colors.brown
|
||||
..strokeCap=StrokeCap.round
|
||||
@@ -85,11 +92,10 @@ class HourglassPainter extends CustomPainter{
|
||||
fallingSand.close();
|
||||
|
||||
final gradient = ui.Gradient.linear(
|
||||
Offset(size.width/2, bottomStartHeight),
|
||||
Offset(size.width/2, bottomEndHeight),
|
||||
Offset(size.width/2, size.height * 0.9),
|
||||
Offset(size.width/2, bottomEndHeight + size.height *0.07),
|
||||
colors,
|
||||
colorStops);
|
||||
|
||||
final bottomContentPainter = Paint()
|
||||
..shader=gradient
|
||||
..style=PaintingStyle.fill
|
||||
@@ -101,8 +107,8 @@ class HourglassPainter extends CustomPainter{
|
||||
canvas.drawPath(topContent, contentPainter);
|
||||
canvas.drawPath(bottomContent, bottomContentPainter);
|
||||
canvas.drawPath(outline, outlinePainter);
|
||||
canvas.drawLine(Offset(0,0),Offset(size.width,0),outlinePainter);
|
||||
canvas.drawLine(Offset(0,size.height),Offset(size.width,size.height),outlinePainter);
|
||||
canvas.drawLine(Offset(0,0),Offset(size.width,0),outlinePainter2);
|
||||
canvas.drawLine(Offset(0,size.height),Offset(size.width,size.height),outlinePainter2);
|
||||
}
|
||||
|
||||
double getTopContentWidthOffset(double width,double height,double fullHeight, double inset){
|
||||
|
||||
@@ -105,12 +105,13 @@ class Queries{
|
||||
}
|
||||
|
||||
class Project{
|
||||
Project(this.name, this.category, this.steps, this.deadline,{this.cat});
|
||||
Project(this.name, this.category, this.steps,this.eta, this.deadline,{this.cat});
|
||||
|
||||
String name;
|
||||
String category;
|
||||
Category? cat;
|
||||
List<ProjectStep> steps;
|
||||
int? eta;
|
||||
DateTime deadline;
|
||||
|
||||
static String colName = "name";
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:tasktracker/Data.dart';
|
||||
import 'package:tasktracker/NewProject.dart';
|
||||
import 'package:tasktracker/NotificationsManager.dart';
|
||||
import 'main.dart';
|
||||
import 'User.dart' as User;
|
||||
@@ -128,7 +129,7 @@ class Dialogs{
|
||||
context=navigatorKey.currentContext;
|
||||
List<Widget> stepWidgets = [];
|
||||
for (ProjectStep value in project.steps) {
|
||||
stepWidgets.add(Text('[${value.progress}%] ${value.eta}h -> ${value.stepName}'));
|
||||
stepWidgets.add(Text('[${value.progress}%] ${value.eta}h -> ${value.stepName}',style: TextStyle(fontSize: 14)));
|
||||
}
|
||||
if(context!=null) {
|
||||
return showDialog(
|
||||
@@ -142,9 +143,10 @@ class Dialogs{
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text("deadline : ${project.deadline}"),
|
||||
Text("Steps"),
|
||||
SizedBox(height: 5),
|
||||
Text("Deadline : ${DateFormat("yyyy-MM-dd").format(project.deadline)}"),
|
||||
Divider(),
|
||||
Text("Steps",style: TextStyle(fontWeight: FontWeight.bold)),
|
||||
SizedBox(height: 20),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
@@ -155,6 +157,7 @@ class Dialogs{
|
||||
actions: [
|
||||
MaterialButton(
|
||||
onPressed: (){
|
||||
User.UserOperations.deleteProject(project.name);
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text('Delete', style:TextStyle(color: Colors.red)),
|
||||
@@ -162,6 +165,7 @@ class Dialogs{
|
||||
MaterialButton(
|
||||
onPressed: (){
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).push(MaterialPageRoute(builder: (context)=>NewProject(multiline: project.steps.isNotEmpty, projectName: project.name, selectedCategory: project.cat!.name,m_steps: project.steps,)));
|
||||
},
|
||||
child: Text('Edit', style:TextStyle(color: Colors.yellow)),
|
||||
),
|
||||
|
||||
@@ -13,10 +13,16 @@ DateFormat dateFormat = DateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
DateFormat durationFormat = DateFormat("HH:mm:ss");
|
||||
|
||||
class NewProject extends StatefulWidget {
|
||||
const NewProject({Key? key}) : super(key: key);
|
||||
NewProject({Key? key,this.multiline,this.projectName,this.selectedCategory, this.m_steps}) : super(key: key);
|
||||
|
||||
late bool? multiline;
|
||||
late String? projectName;
|
||||
late String? selectedCategory;
|
||||
late List<ProjectStep>? m_steps;
|
||||
late int? m_eta;
|
||||
|
||||
@override
|
||||
_NewProjectState createState() => _NewProjectState();
|
||||
_NewProjectState createState() => _NewProjectState(multiline: multiline, pname: projectName, selectedCategory: selectedCategory, m_steps: m_steps);
|
||||
}
|
||||
|
||||
List<String> getCategoryNames() {
|
||||
@@ -27,11 +33,22 @@ List<String> getCategoryNames() {
|
||||
});
|
||||
return _cats;
|
||||
}
|
||||
|
||||
bool editing = false;
|
||||
bool multiLine = true;
|
||||
String selectedCat = User.categories[0].name;
|
||||
|
||||
class _NewProjectState extends State<NewProject> {
|
||||
|
||||
_NewProjectState({bool? multiline, String? pname, String? selectedCategory, List<ProjectStep>? m_steps, int? m_eta}){
|
||||
multiLine=multiline ?? true;
|
||||
nameController.text = pname ?? '';
|
||||
if(selectedCategory!=null){selectedCat = selectedCategory;}
|
||||
if(m_steps!=null){steps=m_steps;}else{print('no steps?');}
|
||||
if(multiline!=null && pname != null && selectedCategory != null && m_steps!=null){
|
||||
editing=true;
|
||||
}
|
||||
}
|
||||
|
||||
TextEditingController nameController = TextEditingController();
|
||||
bool productive = true;
|
||||
Color pickerColor = Colors.blue;
|
||||
@@ -664,7 +681,11 @@ class _NewProject2State extends State<NewProject2> {
|
||||
void OnClickAdd() async{
|
||||
if(projectName==null || deadline.isBefore(DateTime.now())){showAlertDialog(context, 'Error', 'Please make sure you have entered correct information'); return;}
|
||||
|
||||
User.UserOperations.addProject(projectName!, selectedCat, steps, deadline);
|
||||
User.UserOperations.addProject(projectName!, selectedCat, steps,etaHours, deadline);
|
||||
|
||||
Navigator.of(navigatorKey.currentContext!).popUntil((route){
|
||||
return route.isFirst;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,24 @@ class Projects extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _ProjectsState extends State<Projects> {
|
||||
var refreshSub;
|
||||
@override void initState() {
|
||||
// TODO: implement initState
|
||||
super.initState();
|
||||
|
||||
refreshSub = User.refreshStream.stream.listen((event) {
|
||||
setState(() {
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@override void dispose() {
|
||||
// TODO: implement dispose
|
||||
super.dispose();
|
||||
refreshSub?.close();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SafeArea(child: Scaffold(
|
||||
@@ -83,7 +101,7 @@ class _ProjectsState extends State<Projects> {
|
||||
Expanded(
|
||||
child: Card(
|
||||
child:InkWell(
|
||||
onTap: (){
|
||||
onLongPress: (){
|
||||
Dialogs.showProjectDetails(project);
|
||||
},
|
||||
child: Padding(
|
||||
|
||||
@@ -98,7 +98,7 @@ Future<void> BuildBridgeToServer() async{
|
||||
StartActivityTimer(ongoingData[0], ongoingData[1], DateTime.parse(ongoingData[2]));
|
||||
}
|
||||
}else{
|
||||
CancelOngoingActivity();
|
||||
if(prefs.containsKey('current_activity'))CancelOngoingActivity();
|
||||
}
|
||||
|
||||
if(prefs.containsKey('rev')){
|
||||
@@ -659,14 +659,16 @@ Future<List<Project>> GetProjects(bool forceOffline) async {
|
||||
print('steps : $stepsJson');
|
||||
List<dynamic> _steps = jsonDecode(stepsJson);
|
||||
List<ProjectStep> steps = [];
|
||||
int eta = 0;
|
||||
_steps.forEach((element) {
|
||||
ProjectStep step = ProjectStep.fromJson(element);
|
||||
eta+=step.eta;
|
||||
steps.add(step);
|
||||
print(element);
|
||||
});
|
||||
// print(steps);
|
||||
|
||||
_projects.add(Project(name.replaceAll(username, ""),category,steps,DateTime.parse(deadline),cat: cat));
|
||||
_projects.add(Project(name.replaceAll(username, ""),category,steps,eta,DateTime.parse(deadline),cat: cat));
|
||||
}
|
||||
projects = _projects;
|
||||
} else {
|
||||
@@ -1035,13 +1037,14 @@ class UserOperations {
|
||||
await executeQueries();
|
||||
}
|
||||
|
||||
static Future<void> addProject(String name, String category, List<ProjectStep> steps, DateTime deadline) async {
|
||||
static Future<void> addProject(String name, String category, List<ProjectStep> steps,int eta, DateTime deadline) async {
|
||||
Map<String, String> queryBody = <String, String>{
|
||||
'name': username + name,
|
||||
'username': username,
|
||||
'device_id': await Settings.UUID(),
|
||||
'category_id': username + category,
|
||||
'steps': jsonEncode(steps),
|
||||
'eta': eta.toString(),
|
||||
'deadline': DateFormat("yyyy-MM-dd").format(deadline)
|
||||
};
|
||||
|
||||
@@ -1186,6 +1189,43 @@ class UserOperations {
|
||||
}
|
||||
}
|
||||
|
||||
static Future<void> deleteProject(String project, {bulk = false}) async {
|
||||
Map<String, String> queryBody = <String, String>{
|
||||
'username': username,
|
||||
'name': username+project,
|
||||
};
|
||||
//Add Query
|
||||
Map<String, Object> query = {Queries.colLink: 'delete_project', Queries.colData: jsonEncode(queryBody)};
|
||||
|
||||
print("adding new query ${query[Queries.colLink]} : ${jsonEncode(queryBody)}");
|
||||
|
||||
if (cacheEnabled) {
|
||||
await cacheDb.insert('Queries', query);
|
||||
|
||||
//update Cache
|
||||
String deleteQuery =
|
||||
"DELETE FROM Projects WHERE ${Project.colName}='${username+project}'";
|
||||
print("delteQuery : $deleteQuery");
|
||||
|
||||
await cacheDb.rawDelete(deleteQuery);
|
||||
await refreshUserData(forceOffline: true);
|
||||
//Add to server and refresh Cache
|
||||
} else {
|
||||
try {
|
||||
http.Response queryResponse = (await http.post(Uri.parse('http://161.97.127.136/task_tracker/delete_project.php'), body: queryBody));
|
||||
print("Query executed : Results{${queryResponse.body}");
|
||||
if (queryResponse.body.toLowerCase().contains("success")) {
|
||||
//Success
|
||||
}
|
||||
} catch (e) {
|
||||
print('NC: Error deleting project $e}');
|
||||
}
|
||||
}
|
||||
if (!bulk) {
|
||||
await executeQueries();
|
||||
}
|
||||
}
|
||||
|
||||
static Future<void> executeQueries() async {
|
||||
if (cacheEnabled) {
|
||||
if (offline) {
|
||||
|
||||
@@ -195,7 +195,24 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
// if(hourglassTime > 1){
|
||||
// hourglassTime=0;
|
||||
// }
|
||||
hourglassTime = ((DateTime.now().hour * 60) + DateTime.now().minute) / 1440;
|
||||
// hourglassTime = 1;
|
||||
print('hourglass time : $hourglassTime');
|
||||
hourglassColors =[];
|
||||
hourglassStops = [];
|
||||
int testHourglasstime = 0;
|
||||
hourglassCatData.forEach((element) {
|
||||
hourglassColors.add(element.color);
|
||||
hourglassStops.add(element.time/hourglassTotalTime);
|
||||
testHourglasstime += element.time;
|
||||
});
|
||||
print('$testHourglasstime : $hourglassTotalTime');
|
||||
if(hourglassColors.isEmpty){
|
||||
hourglassColors.add(Colors.black);
|
||||
hourglassStops.add(1);
|
||||
}
|
||||
|
||||
print('hourglass \n$hourglassColors \n$hourglassStops');
|
||||
setState(() {
|
||||
|
||||
});
|
||||
@@ -244,19 +261,7 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
}else{
|
||||
ongoingActName = "";
|
||||
}
|
||||
hourglassTime = ((DateTime.now().hour * 60) + DateTime.now().minute) / 1440;
|
||||
print('hourglass time : $hourglassTime');
|
||||
hourglassColors =[];
|
||||
hourglassStops = [];
|
||||
hourglassCatData.forEach((element) {
|
||||
hourglassColors.add(element.color);
|
||||
hourglassStops.add(element.time/hourglassTotalTime);
|
||||
});
|
||||
|
||||
if(hourglassColors.isEmpty){
|
||||
hourglassColors.add(Colors.black);
|
||||
hourglassStops.add(1);
|
||||
}
|
||||
setState(() {
|
||||
|
||||
});
|
||||
@@ -275,7 +280,7 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
Map<String, int> productivtyActs = <String, int>{};
|
||||
Map<String, int> unproductivtyActs = <String, int>{};
|
||||
Map<TaskType, int> taskTypesDuration = <TaskType, int>{};
|
||||
|
||||
hourglassCatData=[];
|
||||
hourglassColors=[];
|
||||
hourglassTotalTime=0;
|
||||
firstDay = null;
|
||||
@@ -350,7 +355,9 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
} else {
|
||||
catTimeMap.putIfAbsent(element.taskType.cat!, () => thisMinutes);
|
||||
}
|
||||
hourglassTotalTime+=thisMinutes;
|
||||
if(thisMinutes > hourglassTotalTime){
|
||||
hourglassTotalTime=thisMinutes;
|
||||
}
|
||||
}
|
||||
|
||||
if ((element.startTime.isAfter(catsRange!.start) && element.startTime.isBefore(catsRange!.end)) ||
|
||||
@@ -388,7 +395,7 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
}
|
||||
|
||||
hourglassCatData.sort((a, b) => a.time.compareTo(b.time));
|
||||
hourglassCatData = hourglassCatData.reversed.toList();
|
||||
// hourglassCatData = hourglassCatData.reversed.toList();
|
||||
}
|
||||
dailyData = <CatMapData>[];
|
||||
productivityData = <ProductivityMapData>[];
|
||||
@@ -596,9 +603,9 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
Container(
|
||||
padding: EdgeInsets.all(10),
|
||||
child: Card(
|
||||
color: Colors.white12,
|
||||
color: Colors.white10,
|
||||
elevation: 20,
|
||||
shadowColor: Colors.brown,
|
||||
shadowColor: Colors.black,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 25, vertical: 20),
|
||||
child: Column(
|
||||
@@ -611,7 +618,7 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
Column(
|
||||
children: [
|
||||
Text(DateFormat("MMMM-dd").format(DateTime.now()),style:TextStyle(fontSize: 18)),
|
||||
Text(DateFormat("hh:mm").format(DateTime.now()),style:TextStyle(fontSize: 40, fontWeight: FontWeight.bold)),
|
||||
Text(DateFormat("hh:mm a").format(DateTime.now()),style:TextStyle(fontSize: 40, fontWeight: FontWeight.bold)),
|
||||
Container(height: 20,)
|
||||
],
|
||||
)
|
||||
@@ -625,8 +632,9 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
height: 350,
|
||||
padding: EdgeInsets.all(10),
|
||||
child: Card(
|
||||
elevation: 8,
|
||||
shadowColor: Colors.blueGrey,
|
||||
color: Colors.white10,
|
||||
elevation: 20,
|
||||
shadowColor: Colors.black,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 20),
|
||||
child: Column(
|
||||
@@ -711,8 +719,9 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
height: 400,
|
||||
padding: EdgeInsets.all(10),
|
||||
child: Card(
|
||||
elevation: 8,
|
||||
shadowColor: Colors.blueGrey,
|
||||
color: Colors.white10,
|
||||
elevation: 20,
|
||||
shadowColor: Colors.black,
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(8),
|
||||
child: (!days.isEmpty)
|
||||
@@ -747,8 +756,9 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
height: (taskTypesData.length * 45).clamp(350, 1000).toDouble(),
|
||||
padding: EdgeInsets.all(10),
|
||||
child: Card(
|
||||
elevation: 8,
|
||||
shadowColor: Colors.blueGrey,
|
||||
color: Colors.white10,
|
||||
elevation: 20,
|
||||
shadowColor: Colors.black,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 25, vertical: 25),
|
||||
child: Column(children: [
|
||||
@@ -787,8 +797,9 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
height: (catsData.length * 45).clamp(350, 1000).toDouble(),
|
||||
padding: EdgeInsets.all(10),
|
||||
child: Card(
|
||||
elevation: 8,
|
||||
shadowColor: Colors.blueGrey,
|
||||
color: Colors.white10,
|
||||
elevation: 20,
|
||||
shadowColor: Colors.black,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 25, vertical: 25),
|
||||
child: Column(children: [
|
||||
|
||||
Reference in New Issue
Block a user