Hourglass improved + projects delete

This commit is contained in:
Sewmina
2022-03-23 19:30:32 +05:30
parent aa72b5dc92
commit 9f976b1e33
7 changed files with 145 additions and 44 deletions

View File

@@ -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){

View File

@@ -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";

View File

@@ -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)),
),

View File

@@ -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;
});
}
}

View File

@@ -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(

View File

@@ -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) {

View File

@@ -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: [