Hourglass
This commit is contained in:
@@ -176,7 +176,7 @@ class _ActivitiesState extends State<Activities> {
|
||||
}
|
||||
|
||||
|
||||
List<Widget> PrintTasks() {
|
||||
List<Widget> PrintTasks() {
|
||||
List<Widget> _tasks = [];
|
||||
print('Priting cats : ' + User.taskTypes.length.toString());
|
||||
String lastDate = "";
|
||||
@@ -303,77 +303,83 @@ class _ActivitiesState extends State<Activities> {
|
||||
|
||||
Widget DateSeperator(date, prodActs, unprodActs) {
|
||||
// double prodPercentage = (prodActs / (prodActs + unprodActs)) * 100;
|
||||
double prodPercentage = (prodActs / 1440) * 100;
|
||||
return Padding(
|
||||
padding: const EdgeInsets.fromLTRB(0, 20, 10, 0),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
|
||||
return FutureBuilder(
|
||||
future: Settings.getUntrackedUnproductive(),
|
||||
builder: (context, snapshot) {
|
||||
double prodPercentage = (User.ParseBool(snapshot.data))? ((prodActs / 1440) * 100) : ((prodActs / unprodActs) * 100);
|
||||
return Padding(
|
||||
padding: const EdgeInsets.fromLTRB(0, 20, 10, 0),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
SizedBox(width: 15,),
|
||||
Icon(Icons.circle),
|
||||
SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Text(
|
||||
date,
|
||||
style: TextStyle(fontSize: 18),
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
if(prodPercentage < 35)Text(Main.MinutesToTimeString(prodActs),),
|
||||
Container(
|
||||
child: Align(
|
||||
child: (prodPercentage >= 35) ?Text(Main.MinutesToTimeString(prodActs),) : Container(),
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
width: (prodPercentage) * 1,
|
||||
height: 20,
|
||||
decoration: BoxDecoration(color: Colors.green, borderRadius: BorderRadius.horizontal(left: Radius.circular(10))),
|
||||
SizedBox(width: 15,),
|
||||
Icon(Icons.circle),
|
||||
SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Container(
|
||||
child: Align(
|
||||
child: (prodPercentage < 35) ?Text(Main.MinutesToTimeString(unprodActs)) :Container(),
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
width: (100 - prodPercentage) * 1,
|
||||
height: 20,
|
||||
decoration: BoxDecoration(color: Colors.red, borderRadius: BorderRadius.horizontal(right: Radius.circular(10))),
|
||||
Text(
|
||||
date,
|
||||
style: TextStyle(fontSize: 18),
|
||||
),
|
||||
if(prodPercentage >= 35)Text(Main.MinutesToTimeString(unprodActs))
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Text(prodPercentage.toStringAsFixed(1) + "%", style: TextStyle(color: Colors.green, fontWeight: FontWeight.bold, fontSize: 20))
|
||||
Row(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
if(prodPercentage < 35)Text(Main.MinutesToTimeString(prodActs),),
|
||||
Container(
|
||||
child: Align(
|
||||
child: (prodPercentage >= 35) ?Text(Main.MinutesToTimeString(prodActs),) : Container(),
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
width: (prodPercentage) * 1,
|
||||
height: 20,
|
||||
decoration: BoxDecoration(color: Colors.green, borderRadius: BorderRadius.horizontal(left: Radius.circular(10))),
|
||||
),
|
||||
Container(
|
||||
child: Align(
|
||||
child: (prodPercentage < 35) ?Text(Main.MinutesToTimeString(unprodActs)) :Container(),
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
width: (100 - prodPercentage) * 1,
|
||||
height: 20,
|
||||
decoration: BoxDecoration(color: Colors.red, borderRadius: BorderRadius.horizontal(right: Radius.circular(10))),
|
||||
),
|
||||
if(prodPercentage >= 35)Text(Main.MinutesToTimeString(unprodActs))
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Text(prodPercentage.toStringAsFixed(1) + "%", style: TextStyle(color: Colors.green, fontWeight: FontWeight.bold, fontSize: 20))
|
||||
],
|
||||
)
|
||||
// CustomPaint(
|
||||
// painter: MyPlayerBar(100, prodPercentage.toInt(),
|
||||
// background: Colors.green, fill: Colors.deepOrange),
|
||||
// child: Container(
|
||||
// alignment: Alignment.center,
|
||||
// height: 25.0,
|
||||
// width: 200,
|
||||
// child: Text(
|
||||
// "Productivity : ${prodPercentage.toStringAsFixed(1)}%",
|
||||
// style: TextStyle(fontWeight: FontWeight.bold),),
|
||||
//
|
||||
// ),
|
||||
// ),
|
||||
],
|
||||
)
|
||||
// CustomPaint(
|
||||
// painter: MyPlayerBar(100, prodPercentage.toInt(),
|
||||
// background: Colors.green, fill: Colors.deepOrange),
|
||||
// child: Container(
|
||||
// alignment: Alignment.center,
|
||||
// height: 25.0,
|
||||
// width: 200,
|
||||
// child: Text(
|
||||
// "Productivity : ${prodPercentage.toStringAsFixed(1)}%",
|
||||
// style: TextStyle(fontWeight: FontWeight.bold),),
|
||||
//
|
||||
// ),
|
||||
// ),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
122
lib/CustomWidgets.dart
Normal file
122
lib/CustomWidgets.dart
Normal file
@@ -0,0 +1,122 @@
|
||||
|
||||
import 'dart:math';
|
||||
import 'dart:ui' as ui;
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class HourglassPainter extends CustomPainter{
|
||||
double fillAmount =0;
|
||||
List<Color> colors = [Colors.black];
|
||||
List<double> colorStops = [1];
|
||||
HourglassPainter(this.fillAmount, this.colors, this.colorStops);
|
||||
@override
|
||||
void paint(Canvas canvas, Size size) {
|
||||
double hourglassCurve = size.height * 0.5;
|
||||
double hourglassInset = size.width / 10;
|
||||
double hourglassHalfHeight = (size.height / 2) - hourglassInset;
|
||||
// const LinearGradient gradient = LinearGradient(
|
||||
// tileMode: TileMode.clamp,
|
||||
// colors: <Color>[
|
||||
// Colors.blue,
|
||||
// Colors.green,
|
||||
// Colors.red// blue sky
|
||||
// ],
|
||||
// stops: <double>[0.2, 0.6,1],
|
||||
// );
|
||||
|
||||
final outlinePainter = Paint()
|
||||
..color=Colors.orangeAccent
|
||||
..strokeCap=StrokeCap.round
|
||||
..strokeWidth=5
|
||||
// ..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
|
||||
..strokeWidth=1;
|
||||
|
||||
|
||||
final outline = Path();
|
||||
|
||||
outline.moveTo(hourglassInset, hourglassInset);
|
||||
outline.arcToPoint(Offset(size.width-hourglassInset,hourglassInset));
|
||||
outline.arcToPoint(Offset(size.width * 0.6,size.height * 0.45),radius: Radius.circular(hourglassCurve),clockwise: true);
|
||||
outline.arcToPoint(Offset(size.width * 0.55,size.height * 0.55),radius: Radius.circular(20),clockwise: false);
|
||||
outline.arcToPoint(Offset(size.width-hourglassInset,size.height-10),radius: Radius.circular(hourglassCurve),clockwise: true);
|
||||
outline.arcToPoint(Offset(hourglassInset, size.height-hourglassInset));
|
||||
outline.arcToPoint(Offset(size.width * 0.45,size.height * 0.55),radius: Radius.circular(hourglassCurve),clockwise: true);
|
||||
outline.arcToPoint(Offset(size.width * 0.4,size.height * 0.45),radius: Radius.circular(20),clockwise: false);
|
||||
outline.arcToPoint(Offset(hourglassInset,hourglassInset),radius: Radius.circular(hourglassCurve),clockwise: true);
|
||||
outline.close();
|
||||
|
||||
final topContent = Path();
|
||||
double topStartHeight = size.height*(0.4 -((1-fillAmount) *0.3));
|
||||
double topEndHeight = size.height * 0.48;
|
||||
double topContentStartWidthOffset = getTopContentWidthOffset(size.width, topStartHeight, hourglassHalfHeight, hourglassInset);
|
||||
double topContentEndWidthOffset = getTopContentWidthOffset(size.width, topEndHeight, hourglassHalfHeight, hourglassInset);
|
||||
// double contentWidthOffset = (((size.width /2) - hourglassInset) * sin((endHeight/hourglassHalfHeight) * (pi/6)));
|
||||
|
||||
topContent.moveTo(topContentStartWidthOffset,topStartHeight);
|
||||
topContent.arcToPoint(Offset(hourglassInset+ topContentEndWidthOffset,topEndHeight), radius: Radius.circular(hourglassCurve),clockwise: false);
|
||||
topContent.arcToPoint(Offset((size.width - hourglassInset)-topContentEndWidthOffset,topEndHeight));
|
||||
topContent.arcToPoint(Offset(size.width - topContentStartWidthOffset,topStartHeight), radius: Radius.circular(hourglassCurve),clockwise: false);
|
||||
topContent.close();
|
||||
|
||||
final bottomContent = Path();
|
||||
double bottomStartHeight = size.height-hourglassInset;
|
||||
double bottomEndHeight = size.height * (0.95 - (fillAmount * 0.32));
|
||||
double bottomContentStartWidthOffset = getBottomContentWidthOffset(size.width, bottomStartHeight, hourglassHalfHeight, hourglassInset);
|
||||
double bottomContentEndWidthOffset = getBottomContentWidthOffset(size.width, bottomEndHeight, hourglassHalfHeight, hourglassInset);
|
||||
// double contentWidthOffset = (((size.width /2) - hourglassInset) * sin((endHeight/hourglassHalfHeight) * (pi/6)));
|
||||
|
||||
bottomContent.moveTo(bottomContentStartWidthOffset,bottomStartHeight);
|
||||
bottomContent.arcToPoint(Offset(hourglassInset+ bottomContentEndWidthOffset,bottomEndHeight), radius: Radius.circular(hourglassCurve),clockwise: true);
|
||||
bottomContent.arcToPoint(Offset(size.width/2,bottomEndHeight-size.height*0.02),);
|
||||
bottomContent.arcToPoint(Offset((size.width - hourglassInset)-bottomContentEndWidthOffset,bottomEndHeight));
|
||||
bottomContent.arcToPoint(Offset(size.width - bottomContentStartWidthOffset,bottomStartHeight), radius: Radius.circular(hourglassCurve),clockwise: true);
|
||||
bottomContent.close();
|
||||
|
||||
final fallingSand = Path();
|
||||
fallingSand.moveTo(size.width*0.4,(size.height*0.48));
|
||||
fallingSand.arcToPoint(Offset(size.width*0.495,(size.height*0.57)));
|
||||
fallingSand.lineTo(size.width*0.48,size.height -hourglassInset);
|
||||
fallingSand.lineTo(size.width*0.52,size.height -hourglassInset);
|
||||
fallingSand.arcToPoint(Offset(size.width*0.505,(size.height*0.57)));
|
||||
fallingSand.arcToPoint(Offset(size.width*0.6,(size.height*0.48)));
|
||||
fallingSand.close();
|
||||
|
||||
final gradient = ui.Gradient.linear(
|
||||
Offset(size.width/2, bottomStartHeight),
|
||||
Offset(size.width/2, bottomEndHeight),
|
||||
colors,
|
||||
colorStops);
|
||||
|
||||
final bottomContentPainter = Paint()
|
||||
..shader=gradient
|
||||
..style=PaintingStyle.fill
|
||||
..strokeCap=StrokeCap.round
|
||||
..strokeWidth=1;
|
||||
|
||||
|
||||
canvas.drawPath(fallingSand, contentPainter);
|
||||
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);
|
||||
}
|
||||
|
||||
double getTopContentWidthOffset(double width,double height,double fullHeight, double inset){
|
||||
return (((width /2) - inset) * sin((height/fullHeight) * (pi/3.8)));
|
||||
}
|
||||
double getBottomContentWidthOffset(double width,double height,double fullHeight, double inset){
|
||||
return (((width /2) - inset) * sin(1-((height/fullHeight) * (pi/8.9))));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
bool shouldRepaint(covariant CustomPainter oldDelegate) {
|
||||
return true;
|
||||
//throw UnimplementedError();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
|
||||
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/NotificationsManager.dart';
|
||||
import 'main.dart';
|
||||
import 'User.dart' as User;
|
||||
@@ -123,6 +124,62 @@ class Dialogs{
|
||||
}
|
||||
}
|
||||
|
||||
static showProjectDetails(Project project) async{
|
||||
context=navigatorKey.currentContext;
|
||||
List<Widget> stepWidgets = [];
|
||||
for (ProjectStep value in project.steps) {
|
||||
stepWidgets.add(Text('[${value.progress}%] ${value.eta}h -> ${value.stepName}'));
|
||||
}
|
||||
if(context!=null) {
|
||||
return showDialog(
|
||||
context: context!,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(30)),
|
||||
backgroundColor: Color(0xFF1C1C1C),
|
||||
title: Text(project.name),
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text("deadline : ${project.deadline}"),
|
||||
Text("Steps"),
|
||||
SizedBox(height: 5),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: stepWidgets,
|
||||
)
|
||||
],
|
||||
),
|
||||
actions: [
|
||||
MaterialButton(
|
||||
onPressed: (){
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text('Delete', style:TextStyle(color: Colors.red)),
|
||||
),
|
||||
MaterialButton(
|
||||
onPressed: (){
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text('Edit', style:TextStyle(color: Colors.yellow)),
|
||||
),
|
||||
MaterialButton(
|
||||
onPressed: (){
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text('Close', style:TextStyle(color: Colors.white)),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
);
|
||||
}else{
|
||||
print('context is null');
|
||||
}
|
||||
}
|
||||
|
||||
static hide(){
|
||||
showing=false;
|
||||
Navigator.of(navigatorKey.currentContext!).popUntil((route){
|
||||
|
||||
@@ -41,6 +41,8 @@ class NotificationManager{
|
||||
if (ongoingActData != null) {
|
||||
List<String> data = ongoingActData.split("<td>");
|
||||
const AndroidNotificationDetails androidNotificationDetails = AndroidNotificationDetails('0', 'Ongoing',
|
||||
enableVibration: false,
|
||||
playSound: false,
|
||||
ongoing: true,
|
||||
autoCancel: false);
|
||||
const NotificationDetails notificationDetails = NotificationDetails(android: androidNotificationDetails);
|
||||
@@ -60,10 +62,10 @@ class NotificationManager{
|
||||
}
|
||||
}catch(e){
|
||||
print("error ongoing activity");
|
||||
await fltrNotification.cancel(1);
|
||||
fltrNotification.cancel(1);
|
||||
}
|
||||
}else{
|
||||
await fltrNotification.cancel(1);
|
||||
fltrNotification.cancel(1);
|
||||
}
|
||||
|
||||
if(adaptive_notification && adaptive_notification_availabel){
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:tasktracker/Data.dart';
|
||||
import 'package:tasktracker/NewProject.dart';
|
||||
import 'Dialogs.dart';
|
||||
import 'User.dart' as User;
|
||||
import 'main.dart';
|
||||
class Projects extends StatefulWidget {
|
||||
@@ -82,7 +83,9 @@ class _ProjectsState extends State<Projects> {
|
||||
Expanded(
|
||||
child: Card(
|
||||
child:InkWell(
|
||||
onTap: (){},
|
||||
onTap: (){
|
||||
Dialogs.showProjectDetails(project);
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(10.0),
|
||||
child: Column(
|
||||
|
||||
240
lib/main.dart
240
lib/main.dart
@@ -24,6 +24,7 @@ import 'Activities.dart';
|
||||
import 'User.dart' as User;
|
||||
import 'package:syncfusion_flutter_charts/charts.dart';
|
||||
import 'Dialogs.dart';
|
||||
import 'CustomWidgets.dart';
|
||||
final GlobalKey<NavigatorState> navigatorKey = new GlobalKey<NavigatorState>();
|
||||
showAlertDialog(BuildContext context, String title, String message) {
|
||||
// set up the button
|
||||
@@ -116,7 +117,7 @@ DateTime? firstDay = null;
|
||||
DateTime? lastDay = null;
|
||||
DateTimeRange? taskTypeRange = null;
|
||||
DateTimeRange? catsRange = null;
|
||||
|
||||
DateTimeRange? prodRange = null;
|
||||
List<ProductivityMapData> productivityData = <ProductivityMapData>[
|
||||
ProductivityMapData('02/24', 35),
|
||||
ProductivityMapData('02/25', 28),
|
||||
@@ -140,6 +141,8 @@ List<CatMapData> dailyData = <CatMapData>[
|
||||
CatMapData('Apr', 32, Colors.grey),
|
||||
];
|
||||
|
||||
List<CatMapData> hourglassCatData = <CatMapData>[];
|
||||
|
||||
class MyHomePage extends StatefulWidget {
|
||||
const MyHomePage({Key? key}) : super(key: key);
|
||||
|
||||
@@ -175,7 +178,10 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
startLoadStatRefresher();
|
||||
// User.progressDialog=progressDialog;
|
||||
}
|
||||
|
||||
double hourglassTime = 0;
|
||||
List<Color> hourglassColors = [Colors.black];
|
||||
List<double> hourglassStops = [1];
|
||||
int hourglassTotalTime = 0;
|
||||
void startLoadStatRefresher() async{
|
||||
int lastMinute = 0;
|
||||
while(true){
|
||||
@@ -185,6 +191,14 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
LoadStats();
|
||||
}
|
||||
await Refresh();
|
||||
// hourglassTime+=0.05;
|
||||
// if(hourglassTime > 1){
|
||||
// hourglassTime=0;
|
||||
// }
|
||||
|
||||
setState(() {
|
||||
|
||||
});
|
||||
await Future.delayed(Duration(seconds: 1));
|
||||
}
|
||||
}
|
||||
@@ -230,6 +244,19 @@ 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(() {
|
||||
|
||||
});
|
||||
@@ -248,6 +275,9 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
Map<String, int> productivtyActs = <String, int>{};
|
||||
Map<String, int> unproductivtyActs = <String, int>{};
|
||||
Map<TaskType, int> taskTypesDuration = <TaskType, int>{};
|
||||
|
||||
hourglassColors=[];
|
||||
hourglassTotalTime=0;
|
||||
firstDay = null;
|
||||
lastDay = null;
|
||||
String lastDate = "";
|
||||
@@ -265,6 +295,10 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
print("$lastDay - $firstDay");
|
||||
catsRange = DateTimeRange(start: lastDay!.subtract(const Duration(days: 0)), end: lastDay!);
|
||||
}
|
||||
if (prodRange == null) {
|
||||
print("$lastDay - $firstDay");
|
||||
prodRange = DateTimeRange(start: lastDay!.subtract(const Duration(days: 7)), end: lastDay!);
|
||||
}
|
||||
firstDay = element.startTime;
|
||||
String thisDate = dFormat.format(element.startTime);
|
||||
|
||||
@@ -286,21 +320,25 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
}
|
||||
}
|
||||
|
||||
if (element.taskType.cat?.productive ?? false) {
|
||||
if(lastProductive==null){lastProductive = element.trueEndTime;}
|
||||
if (productivtyActs.containsKey(thisDate)) {
|
||||
productivtyActs[thisDate] = (productivtyActs[thisDate]! + 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 (lastProductive == null) {
|
||||
lastProductive = element.trueEndTime;
|
||||
}
|
||||
if (productivtyActs.containsKey(thisDate)) {
|
||||
productivtyActs[thisDate] = (productivtyActs[thisDate]! + thisMinutes);
|
||||
} else {
|
||||
productivtyActs.putIfAbsent(thisDate, () => thisMinutes);
|
||||
}
|
||||
} else {
|
||||
productivtyActs.putIfAbsent(thisDate, () => thisMinutes);
|
||||
}
|
||||
} else {
|
||||
if (unproductivtyActs.containsKey(thisDate)) {
|
||||
unproductivtyActs[thisDate] = (unproductivtyActs[thisDate]! + thisMinutes);
|
||||
} else {
|
||||
unproductivtyActs.putIfAbsent(thisDate, () => thisMinutes);
|
||||
if (unproductivtyActs.containsKey(thisDate)) {
|
||||
unproductivtyActs[thisDate] = (unproductivtyActs[thisDate]! + thisMinutes);
|
||||
} else {
|
||||
unproductivtyActs.putIfAbsent(thisDate, () => thisMinutes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (thisDate == curDay) {
|
||||
if (element.taskType.cat == null) {
|
||||
continue;
|
||||
@@ -312,6 +350,7 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
} else {
|
||||
catTimeMap.putIfAbsent(element.taskType.cat!, () => thisMinutes);
|
||||
}
|
||||
hourglassTotalTime+=thisMinutes;
|
||||
}
|
||||
|
||||
if ((element.startTime.isAfter(catsRange!.start) && element.startTime.isBefore(catsRange!.end)) ||
|
||||
@@ -326,57 +365,84 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
catBriefMap.putIfAbsent(element.taskType.cat!, () => thisMinutes);
|
||||
}
|
||||
}
|
||||
|
||||
if(dFormat.format(element.startTime) == dFormat.format(DateTime.now())){
|
||||
if (element.taskType.cat == null) {
|
||||
continue;
|
||||
}
|
||||
print("Null : ${thisMinutes}");
|
||||
|
||||
int? existingEntryIndex;
|
||||
|
||||
for(int i=0; i < hourglassCatData.length; i++){
|
||||
if(hourglassCatData[i].name == element.taskType.category){
|
||||
existingEntryIndex=i;
|
||||
}
|
||||
}
|
||||
|
||||
if (existingEntryIndex==null) {
|
||||
hourglassCatData.add(CatMapData(element.taskType.category, thisMinutes, HexColor.fromHex(element.taskType.cat!.color)));
|
||||
} else {
|
||||
hourglassCatData[existingEntryIndex!].time+=thisMinutes;
|
||||
}
|
||||
}
|
||||
|
||||
hourglassCatData.sort((a, b) => a.time.compareTo(b.time));
|
||||
hourglassCatData = hourglassCatData.reversed.toList();
|
||||
}
|
||||
dailyData = <CatMapData>[];
|
||||
productivityData = <ProductivityMapData>[];
|
||||
taskTypesData = <TaskTypeMapData>[];
|
||||
catsData = <CatMapData>[];
|
||||
int trackedTime = 0;
|
||||
catTimeMap.forEach((key, value) {
|
||||
//print(key.name + " : $value");
|
||||
Color barCol = HexColor.fromHex(key.color);
|
||||
dailyData.add(CatMapData(key.name, value, barCol));
|
||||
trackedTime += value;
|
||||
});
|
||||
int untrackedTime = 1440-trackedTime;
|
||||
if(untrackedTime<0){
|
||||
User.refreshUserData().then((val)=>LoadStats());
|
||||
print("Shit went wrong!");
|
||||
}
|
||||
print("Tracked time : $trackedTime");
|
||||
|
||||
dailyData.sort((a, b) {
|
||||
return a.name.toLowerCase().compareTo(b.name.toLowerCase());
|
||||
});
|
||||
if(untrackedTime> 0){dailyData.add(CatMapData("Untracked",1440-trackedTime, Colors.black));}else{}
|
||||
bool untrackedUnprod = await Settings.getUntrackedUnproductive();
|
||||
for (var element in days) {
|
||||
// if(productivtyActs.containsKey(element) && unproductivtyActs.containsKey(element)){
|
||||
int prodActs = (productivtyActs[element] ?? 0);
|
||||
int unprodActs = (unproductivtyActs[element] ?? 0);
|
||||
double prod = (untrackedUnprod) ? ((prodActs / 1440) * 100) : ((prodActs / unprodActs)*100);
|
||||
if(prod>0){
|
||||
productivityData.add(ProductivityMapData(element, prod));
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
taskTypesDuration.forEach((key, value) {
|
||||
print("$key : $value");
|
||||
taskTypesData.add(TaskTypeMapData(key.name, value, HexColor.fromHex(key.cat!.color)));
|
||||
});
|
||||
|
||||
taskTypesData.sort((a, b) {
|
||||
return a.time.compareTo(b.time);
|
||||
});
|
||||
|
||||
catBriefMap.forEach((key, value) {
|
||||
print(key.name + " : $value");
|
||||
Color barCol = HexColor.fromHex(key.color);
|
||||
catsData.add(CatMapData(key.name, value, barCol));
|
||||
});
|
||||
catsData.sort((a, b) => a.time.compareTo(b.time));
|
||||
//curDay = days[0];
|
||||
if (this.mounted) {
|
||||
setState(() {
|
||||
dailyData = <CatMapData>[];
|
||||
productivityData = <ProductivityMapData>[];
|
||||
taskTypesData = <TaskTypeMapData>[];
|
||||
catsData = <CatMapData>[];
|
||||
int trackedTime = 0;
|
||||
catTimeMap.forEach((key, value) {
|
||||
//print(key.name + " : $value");
|
||||
Color barCol = HexColor.fromHex(key.color);
|
||||
dailyData.add(CatMapData(key.name, value, barCol));
|
||||
trackedTime += value;
|
||||
});
|
||||
int untrackedTime = 1440-trackedTime;
|
||||
if(untrackedTime<0){
|
||||
User.refreshUserData().then((val)=>LoadStats());
|
||||
print("Shit went wrong!");
|
||||
}
|
||||
print("Tracked time : $trackedTime");
|
||||
|
||||
dailyData.sort((a, b) {
|
||||
return a.name.toLowerCase().compareTo(b.name.toLowerCase());
|
||||
});
|
||||
if(untrackedTime> 0){dailyData.add(CatMapData("Untracked",1440-trackedTime, Colors.black));}else{}
|
||||
for (var element in days) {
|
||||
// if(productivtyActs.containsKey(element) && unproductivtyActs.containsKey(element)){
|
||||
int prodActs = (productivtyActs[element] ?? 0);
|
||||
int unprodActs = (unproductivtyActs[element] ?? 0);
|
||||
double prod = (prodActs / 1440) * 100;
|
||||
productivityData.add(ProductivityMapData(element, prod));
|
||||
// }
|
||||
}
|
||||
|
||||
taskTypesDuration.forEach((key, value) {
|
||||
print("$key : $value");
|
||||
taskTypesData.add(TaskTypeMapData(key.name, value, HexColor.fromHex(key.cat!.color)));
|
||||
});
|
||||
|
||||
taskTypesData.sort((a, b) {
|
||||
return a.time.compareTo(b.time);
|
||||
});
|
||||
|
||||
catBriefMap.forEach((key, value) {
|
||||
print(key.name + " : $value");
|
||||
Color barCol = HexColor.fromHex(key.color);
|
||||
catsData.add(CatMapData(key.name, value, barCol));
|
||||
});
|
||||
catsData.sort((a, b) => a.time.compareTo(b.time));
|
||||
});
|
||||
}
|
||||
// loadingStats=false;
|
||||
@@ -527,6 +593,34 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
),
|
||||
)),
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.all(10),
|
||||
child: Card(
|
||||
color: Colors.white12,
|
||||
elevation: 20,
|
||||
shadowColor: Colors.brown,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 25, vertical: 20),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
Container(width:100,height: 150,child: CustomPaint(painter: HourglassPainter(hourglassTime, hourglassColors, hourglassStops),)),
|
||||
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)),
|
||||
Container(height: 20,)
|
||||
],
|
||||
)
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
)),
|
||||
),
|
||||
Container(
|
||||
height: 350,
|
||||
padding: EdgeInsets.all(10),
|
||||
@@ -537,14 +631,26 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 20),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Text("Productivity", style: TextStyle(color: Colors.green, fontWeight: FontWeight.bold)),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10,vertical: 0),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text("Productivity", style: TextStyle(color: Colors.green, fontWeight: FontWeight.bold)),
|
||||
InkWell(
|
||||
onTap: () async {
|
||||
DateTimeRange? value = await showDateRangePicker(context: context, firstDate: firstDay ?? DateTime.now(), lastDate: lastDay ?? DateTime.now());
|
||||
if (value != null) {
|
||||
prodRange = value;
|
||||
}
|
||||
|
||||
],
|
||||
LoadStats();
|
||||
},
|
||||
child: Text((prodRange != null) ? (DateFormat("MM/dd").format(prodRange!.start) + " - " + DateFormat("MM/dd").format(prodRange!.end)) : 'n/a'),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(),
|
||||
Row(
|
||||
@@ -928,7 +1034,7 @@ class MyPlayerBar extends CustomPainter {
|
||||
class CatMapData {
|
||||
CatMapData(this.name, this.time, this.color);
|
||||
final String name;
|
||||
final int time;
|
||||
int time;
|
||||
final Color color;
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,12 @@ class _NewActivity extends State<NewActivity> {
|
||||
|
||||
List<String> getActivities(){
|
||||
List<String> _cats = [];
|
||||
print(User.taskTypes[0].name + " : " + selectedCat);
|
||||
_cats.add("+Add New Task Type");
|
||||
if(User.taskTypes.isEmpty){
|
||||
|
||||
}else {
|
||||
print(User.taskTypes[0].name + " : " + selectedCat);
|
||||
}
|
||||
User.taskTypes.forEach((element) {
|
||||
String name = element.name;
|
||||
if(_cats.contains(element.name)){
|
||||
|
||||
Reference in New Issue
Block a user