Hourglass

This commit is contained in:
Sewmina
2022-03-23 03:41:05 +05:30
parent acfb03d7a3
commit aa72b5dc92
7 changed files with 432 additions and 131 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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