Settings page added

This commit is contained in:
warlock
2022-03-03 06:21:31 +05:30
parent 4576957b4c
commit 7f50983e11
12 changed files with 493 additions and 173 deletions

View File

@@ -17,64 +17,132 @@ class Activities extends StatefulWidget {
late ProgressDialog progressDialog; late ProgressDialog progressDialog;
class _ActivitiesState extends State<Activities> { class _ActivitiesState extends State<Activities> {
TextEditingController searchController = TextEditingController();
FocusNode _focus = FocusNode();
bool searching = false;
void _onFocusChange() {
print("FOCUS CHANGED! : ${_focus.hasFocus}");
if(!_focus.hasFocus){
searching=false;
setState(() {
});
}
}
@override @override
void initState() { void initState() {
// TODO: implement initState // TODO: implement initState
super.initState(); super.initState();
_focus.addListener(_onFocusChange);
UpdateList(); UpdateList();
} }
@override
void dispose() {
// TODO: implement dispose
super.dispose();
_focus.removeListener(_onFocusChange);
_focus.dispose();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
progressDialog = ProgressDialog(context: context); progressDialog = ProgressDialog(context: context);
return Scaffold( return Scaffold(
floatingActionButton: FloatingActionButton.extended( floatingActionButton: FloatingActionButton.extended(
onPressed: () { onPressed: () {
Navigator.of(context) Navigator.of(context).push(MaterialPageRoute(builder: (context) => NewActivity())).then((value) => UpdateList());
.push(MaterialPageRoute(builder: (context) => NewActivity()))
.then((value) => UpdateList());
}, },
label: Text("New Activity"), label: Text("New Activity"),
icon: Icon(Icons.add)), icon: Icon(Icons.add)),
appBar: AppBar( appBar: AppBar(
title: Row( title: (searching)
mainAxisSize: MainAxisSize.max, ? Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisSize: MainAxisSize.max,
children: [ children: [
Row(children: [ Expanded(
Icon(Icons.task, color: Theme.of(context).primaryColor), child: TextField(onChanged: (text){setState(() {
SizedBox(width: 10),
Text('Activities') });},controller: searchController, focusNode: _focus, decoration: InputDecoration(
]), filled: true,
(selecting) ),),
? Row(children: [ ),
InkWell( InkWell(
onTap: () { onTap: (){searching=false;
DeleteSelectedTasks(); searchController.clear();
}, setState(() {
child: Icon(
Icons.delete, });},
size: 30, child: Container(
)), padding: EdgeInsets.symmetric(horizontal: 10),
SizedBox( child: Icon(Icons.cancel),
width: 20, ),
), )
InkWell( ],
onTap: () { )
setState(() { : Row(
selecting = false; mainAxisSize: MainAxisSize.max,
}); mainAxisAlignment: MainAxisAlignment.spaceBetween,
}, children: [
child: Icon(Icons.close, size: 30), Row(children: [Icon(Icons.task, color: Theme.of(context).primaryColor), SizedBox(width: 10), Text('Activities')]),
) (selecting)
]) ? Row(children: [
: Container(), InkWell(
], onTap: () {
)), DeleteSelectedTasks();
},
child: Icon(
Icons.delete,
size: 30,
)),
SizedBox(
width: 20,
),
InkWell(
onTap: () {
setState(() {
selecting = false;
});
},
child: Icon(Icons.close, size: 30),
)
])
: Row(
children: [
InkWell(
onTap: () {
searching = true;
_focus.requestFocus();
setState(() {
});
},
child: Icon(
Icons.search,
size: 30,
)),
SizedBox(
width: 20,
),
InkWell(
onTap: () {
setState(() async {
await User.refreshUserData();
UpdateList();
});
},
child: Icon(Icons.refresh, size: 30),
)
],
),
],
)),
drawer: navDrawer(context, 2), drawer: navDrawer(context, 2),
body: Container( body: Container(
padding: EdgeInsets.all(10), padding: EdgeInsets.all(0),
child: SingleChildScrollView( child: SingleChildScrollView(
child: Column( child: Column(
children: PrintTasks(), children: PrintTasks(),
@@ -102,12 +170,12 @@ class _ActivitiesState extends State<Activities> {
Map<String, int> totalMinutes = <String, int>{}; Map<String, int> totalMinutes = <String, int>{};
for (var element in User.activities) { for (var element in User.activities) {
String thisDate = dFormat.format(element.startTime); String thisDate = dFormat.format(element.startTime);
int thisMinutes= element.endTime.difference(element.startTime).inMinutes; int thisMinutes = element.endTime.difference(element.startTime).inMinutes;
if(totalMinutes.containsKey(thisDate)){ if (totalMinutes.containsKey(thisDate)) {
if((totalMinutes[thisDate]??0) < thisMinutes){ if ((totalMinutes[thisDate] ?? 0) < thisMinutes) {
totalMinutes[thisDate] = thisMinutes; totalMinutes[thisDate] = thisMinutes;
} }
}else{ } else {
totalMinutes.putIfAbsent(thisDate, () => thisMinutes); totalMinutes.putIfAbsent(thisDate, () => thisMinutes);
} }
@@ -127,6 +195,14 @@ class _ActivitiesState extends State<Activities> {
} }
print(productivtyActs); print(productivtyActs);
for (var element in User.activities) { for (var element in User.activities) {
if(searching){
if(element.metadata!.toLowerCase().contains(searchController.text.toLowerCase()) || element.taskType.name.toLowerCase().contains(searchController.text.toLowerCase())){
//Good to go
}else{
continue;
}
}
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;
@@ -138,11 +214,9 @@ class _ActivitiesState extends State<Activities> {
if (element.taskType.cat == null) { if (element.taskType.cat == null) {
print('Got some null cat : ${element.taskType.name}'); print('Got some null cat : ${element.taskType.name}');
} else { } else {
Color color = Color color = HexColor.fromHex(element.taskType.cat?.color ?? '#000000');
HexColor.fromHex(element.taskType.cat?.color ?? '#000000');
bool productive = element.taskType.cat?.productive ?? true; bool productive = element.taskType.cat?.productive ?? true;
Widget task = ActivityCard(context, name, element.startTime, Widget task = ActivityCard(context, name, element.startTime, element.endTime, productive, color, element, totalMinutes[thisDate] ?? 0);
element.endTime, productive, color, element, totalMinutes[thisDate] ?? 0);
_tasks.add(task); _tasks.add(task);
} }
} }
@@ -153,27 +227,55 @@ class _ActivitiesState extends State<Activities> {
Widget DateSeperator(date, prodActs, unprodActs) { Widget DateSeperator(date, prodActs, unprodActs) {
double prodPercentage = (prodActs / (prodActs + unprodActs)) * 100; double prodPercentage = (prodActs / (prodActs + unprodActs)) * 100;
return Padding( return Padding(
padding: const EdgeInsets.fromLTRB(10, 20, 10, 0), padding: const EdgeInsets.fromLTRB(0, 20, 10, 0),
child: Column( child: Column(
children: [ children: [
Row( Row(
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text( Row(
date, children: [
style: TextStyle(fontSize: 18), Icon(Icons.remove_circle_outline),
SizedBox(
width: 10,
),
Text(
date,
style: TextStyle(fontSize: 18),
),
],
), ),
Row(children: [ Row(
Row( children: [
children: [ Row(
Container(child:Align(child:Text(MinutesToTimeString(prodActs)), alignment: Alignment.center,),width: (prodPercentage) * 1.7, height: 25,decoration: BoxDecoration(color: Colors.green,borderRadius: BorderRadius.horizontal(left: Radius.circular(10))),), children: [
Container(child:Align(child:Text(MinutesToTimeString(unprodActs)), alignment: Alignment.center,),width: (100-prodPercentage)* 1.7,height: 25,decoration: BoxDecoration(color: Colors.red,borderRadius: BorderRadius.horizontal(right: Radius.circular(10))),), Container(
], child: Align(
), child: FittedBox(fit: BoxFit.fitWidth,child: Text(MinutesToTimeString(prodActs),)),
SizedBox(width: 10,), alignment: Alignment.center,
Text(prodPercentage.toStringAsFixed(1) + "%",style: TextStyle(color: Colors.green, fontWeight: FontWeight.bold,fontSize: 20)) ),
],) width: (prodPercentage) * 1.7,
height: 25,
decoration: BoxDecoration(color: Colors.green, borderRadius: BorderRadius.horizontal(left: Radius.circular(10))),
),
Container(
child: Align(
child: Text(MinutesToTimeString(unprodActs)),
alignment: Alignment.center,
),
width: (100 - prodPercentage) * 1.7,
height: 25,
decoration: BoxDecoration(color: Colors.red, borderRadius: BorderRadius.horizontal(right: Radius.circular(10))),
),
],
),
SizedBox(
width: 10,
),
Text(prodPercentage.toStringAsFixed(1) + "%", style: TextStyle(color: Colors.green, fontWeight: FontWeight.bold, fontSize: 20))
],
)
// CustomPaint( // CustomPaint(
// painter: MyPlayerBar(100, prodPercentage.toInt(), // painter: MyPlayerBar(100, prodPercentage.toInt(),
// background: Colors.green, fill: Colors.deepOrange), // background: Colors.green, fill: Colors.deepOrange),
@@ -195,20 +297,14 @@ class _ActivitiesState extends State<Activities> {
} }
bool selecting = false; bool selecting = false;
Widget ActivityCard(BuildContext context, String name, DateTime sTime, Widget ActivityCard(BuildContext context, String name, DateTime sTime, DateTime eTime, bool productive, Color color, Activity activity, int totalMinutes) {
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') && bool containsMetadata = ((activity.metadata ?? 'null') != 'null') && ((activity.metadata ?? '').isNotEmpty);
((activity.metadata ?? '').isNotEmpty);
var _timeSpan = eTime.difference(sTime); var _timeSpan = eTime.difference(sTime);
String timeSpan = String timeSpan = ((_timeSpan.inHours > 0) ? _timeSpan.inHours.toString() + 'h ' : '') + ((_timeSpan.inMinutes % 60 > 0) ? (_timeSpan.inMinutes % 60).toString() + 'm' : '');
((_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)
@@ -219,84 +315,77 @@ class _ActivitiesState extends State<Activities> {
OnItemSelected(activity); OnItemSelected(activity);
setState(() {}); setState(() {});
}) })
: Container(), : Container(padding: EdgeInsets.fromLTRB(10, 0, 5, 0), child: SizedBox(width: 1, height: 100, child: Container(color: Colors.white))),
Expanded( Expanded(
child: Column(children: [ child: Column(children: [
Card( Padding(
padding: const EdgeInsets.fromLTRB(0, 0, 5, 0),
child: Card(
// color: color, // color: color,
elevation: 20, elevation: 20,
shadowColor: color, shadowColor: color,
child: InkWell( child: InkWell(
onTap: () { onTap: () {
//Open Respective Category //Open Respective Category
if (selecting) { if (selecting) {
OnItemSelected(activity); OnItemSelected(activity);
} }
setState(() {}); setState(() {});
}, },
onLongPress: () { onLongPress: () {
print('gonna delete'); print('gonna delete');
selecting = !selecting; selecting = !selecting;
selectedActivities = [activity]; selectedActivities = [activity];
setState(() {}); setState(() {});
}, },
child: Container( child: Container(
padding: EdgeInsets.all(15), padding: EdgeInsets.all(15),
child: Column( child: Column(
children: [ children: [
Row( Row(mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
mainAxisSize: MainAxisSize.max, Row(children: [
mainAxisAlignment: MainAxisAlignment.spaceBetween, Text(name + " [$timeSpan]", style: TextStyle(fontSize: 17)),
children: [ if (containsMetadata)
Row(children: [ Icon(
Text(name + " [$timeSpan]", Icons.arrow_forward_outlined,
style: TextStyle( fontSize: 17)), size: 20,
if (containsMetadata) ),
Icon(Icons.arrow_forward_outlined, size: 20,), if (containsMetadata)
if (containsMetadata) Text(
Text(activity.metadata ?? '',overflow: TextOverflow.clip,) activity.metadata ?? '',
]), overflow: TextOverflow.ellipsis,
)
// Icon(Icons.analytics, color: color, size: 20,),
]), ]),
SizedBox(
height: 5, // Icon(Icons.analytics, color: color, size: 20,),
), ]),
Row( SizedBox(
mainAxisSize: MainAxisSize.max, height: 5,
mainAxisAlignment: MainAxisAlignment.spaceBetween, ),
children: [ Row(mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
Text(dateFormat.format(sTime) + Text(dateFormat.format(sTime) + " - " + dateFormat.format(eTime)),
" - " + SizedBox(
dateFormat.format(eTime)), width: 20,
SizedBox( ),
width: 20, Container(
), padding: EdgeInsets.symmetric(horizontal: 10, vertical: 2),
Container( decoration: BoxDecoration(borderRadius: BorderRadius.circular(10), color: (productive) ? Colors.green : Colors.red),
padding: EdgeInsets.symmetric( child: Text(activity.taskType.cat?.name ?? 'n/a'))
horizontal: 10, vertical: 2), // Icon(Icons.circle,
decoration: BoxDecoration( // color: (productive)
borderRadius: BorderRadius.circular(10), // ? Colors.green
color: (productive) // : Colors.red)
? Colors.green ])
: Colors.red), ],
child: Text( )))),
activity.taskType.cat?.name ?? 'n/a')) ),
// Icon(Icons.circle,
// color: (productive)
// ? Colors.green
// : Colors.red)
])
],
)))),
Container( Container(
margin: EdgeInsets.fromLTRB(15, 0, 15, 10), margin: EdgeInsets.fromLTRB(15, 0, 15, 10),
height: 2, height: 2,
child:Row(children: [ child: Row(
Expanded(flex:timePercentage ,child: Container(color:color)), children: [Expanded(flex: timePercentage, child: Container(color: color)), Expanded(flex: 100 - timePercentage, child: Container())],
Expanded(flex:100-timePercentage,child:Container()) )),
],)),
]), ]),
), ),
]); ]);
@@ -311,8 +400,7 @@ class _ActivitiesState extends State<Activities> {
} }
void DeleteSelectedTasks() async { void DeleteSelectedTasks() async {
progressDialog.show( progressDialog.show(max: 100, msg: 'Deleteing ${selectedActivities.length} Activities');
max: 100, msg: 'Deleteing ${selectedActivities.length} Activities');
selectedActivities.forEach((element) async { selectedActivities.forEach((element) async {
await User.UserOperations.deleteActivity(element, bulk: true); await User.UserOperations.deleteActivity(element, bulk: true);
}); });
@@ -328,7 +416,4 @@ class _ActivitiesState extends State<Activities> {
} }
} }
List<Activity> selectedActivities = []; List<Activity> selectedActivities = [];

View File

@@ -122,7 +122,6 @@ class _CategoriesState extends State<Categories> {
Expanded( Expanded(
child: Column(children: [ child: Column(children: [
Card( Card(
// color: color, // color: color,
elevation:20, elevation:20,
shadowColor: color, shadowColor: color,

View File

@@ -1,5 +1,9 @@
import 'dart:async';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:uuid/uuid.dart'; import 'package:uuid/uuid.dart';
import 'theme_provider.dart';
import 'package:provider/provider.dart';
class Category{ class Category{
Category(this.category_id, this.name, this.color, this.productive); Category(this.category_id, this.name, this.color, this.productive);
@@ -80,8 +84,9 @@ class Queries{
} }
class Settings{
class Settings{
static Future<String> UUID() async{ static Future<String> UUID() async{
final prefs = await SharedPreferences.getInstance(); final prefs = await SharedPreferences.getInstance();
if(prefs.containsKey('uuid')){ if(prefs.containsKey('uuid')){
@@ -93,4 +98,11 @@ class Settings{
return Future.value(_uuid); return Future.value(_uuid);
} }
} }
}
static Future<void> setTheme(int value) async{
final prefs = await SharedPreferences.getInstance();
await prefs.setInt("theme", value);
}
}
final settings = Settings();

View File

@@ -0,0 +1,49 @@
import 'package:flutter/material.dart';
import 'package:tasktracker/Settings/Settings.dart';
import 'package:tasktracker/Data.dart';
import 'package:tasktracker/theme_provider.dart';
import 'package:provider/provider.dart';
class AppearanceSettings extends StatefulWidget {
const AppearanceSettings({Key? key}) : super(key: key);
@override
_AppearanceSettingsState createState() => _AppearanceSettingsState();
}
class _AppearanceSettingsState extends State<AppearanceSettings> {
@override
Widget build(BuildContext context) {
final themeProvider= Provider.of<ThemeProvider>(context);
return Scaffold(
appBar: AppBar(title: Text('Appearance Settings')),
body: SafeArea(
child: Container(
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
SizedBox(height: 10,),
Padding(
padding: const EdgeInsets.all(5.0),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text("Dark Mode",style: TextStyle(fontSize: 18)),
Switch.adaptive(value: themeProvider.isDarkMode, onChanged: (value){
final provider = Provider.of<ThemeProvider>(context, listen: false);
provider.toggleTheme(value);
Settings.setTheme(value ? 0:1);
})
],
),
),
Divider(),
],
),
),
)
);
}
}

View File

@@ -0,0 +1,37 @@
import 'package:flutter/material.dart';
class NotificationSettings extends StatefulWidget {
const NotificationSettings({Key? key}) : super(key: key);
@override
_NotificationSettingsState createState() => _NotificationSettingsState();
}
class _NotificationSettingsState extends State<NotificationSettings> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Notification Settings")),
body: SafeArea(
child: Column(
children: [
SizedBox(
height: 10,
),
ListTile(
title: Text("New Activity Notification"),
trailing: InkWell(onTap:(){},child: Text("1 hour")),
subtitle: Text("Notify you to track activities of past time"),
),
Divider(),
ListTile(
title: Text("Suggestion Notifications"), trailing:Switch.adaptive(value: true, onChanged: (val){}),
subtitle: Text("Notifies you about suggestions according to your data"),
)
],
),
),
);
}
}

View File

@@ -0,0 +1,48 @@
import 'package:flutter/material.dart';
import 'package:tasktracker/Settings/AppearanceSettings.dart';
import 'package:tasktracker/Settings/NotificationSettings.dart';
import 'package:tasktracker/main.dart';
class SettingsPage extends StatefulWidget {
const SettingsPage({Key? key}) : super(key: key);
@override
_SettingsPageState createState() => _SettingsPageState();
}
class _SettingsPageState extends State<SettingsPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Settings')),
body: Column(
mainAxisSize: MainAxisSize.max,
children: [
SettingItem('Appearance', ()=>Navigator.of(context).push(MaterialPageRoute(builder: (context)=> const AppearanceSettings()))),
Divider(),
SettingItem('Notifications', ()=>Navigator.of(context).push(MaterialPageRoute(builder: (context)=> const NotificationSettings()))),
],
)
);
}
}
Widget SettingItem(String name, Function onTap){
return InkWell(
onTap: ()=>onTap(),
child: Padding(
padding: const EdgeInsets.all(15.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.max,
children: [
Text(name, style: TextStyle(fontSize: 18)),
Icon(Icons.arrow_forward,size: 20,)
],
),
)
);
}

View File

@@ -23,6 +23,7 @@ List<TaskType> taskTypes = [];
List<Activity> activities=[]; List<Activity> activities=[];
bool offline = true; bool offline = true;
bool registered = false; bool registered = false;
bool refreshing = true;
Future<http.Response> login(String _username, String password) async { Future<http.Response> login(String _username, String password) async {
final prefs = await SharedPreferences.getInstance(); final prefs = await SharedPreferences.getInstance();
@@ -64,6 +65,7 @@ Future<void> initUserData() async {
bool userDataInitiated =false; bool userDataInitiated =false;
Future<void> refreshUserData() async{ Future<void> refreshUserData() async{
ShowProgress("Loading data"); ShowProgress("Loading data");
refreshing = true;
// categories= await GetCategories(true); // categories= await GetCategories(true);
// taskTypes= await GetTaskTypes(true); // taskTypes= await GetTaskTypes(true);
// activities= await GetActivities(true); // activities= await GetActivities(true);
@@ -71,6 +73,7 @@ Future<void> refreshUserData() async{
await updateTasksList(); await updateTasksList();
await updateActList(); await updateActList();
userDataInitiated=true; userDataInitiated=true;
refreshing = false;
HideProgress(); HideProgress();
} }

View File

@@ -1,9 +1,12 @@
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
import 'package:tasktracker/Categories.dart'; import 'package:tasktracker/Categories.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 'Settings/Settings.dart';
import 'package:wakelock/wakelock.dart'; import 'package:wakelock/wakelock.dart';
import 'Data.dart'; import 'Data.dart';
import 'NewTask.dart'; import 'NewTask.dart';
@@ -69,21 +72,28 @@ class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key); const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application. // This widget is the root of your application.
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) => ChangeNotifierProvider(
return MaterialApp( create: (context)=>ThemeProvider(),
title: 'Flutter Demo', builder: (context, _){
theme: ThemeData(accentColor: Colors.redAccent, brightness: Brightness.dark, primaryColor: Colors.amber, fontFamily: 'Noto-Sans'), final themeProvider = Provider.of<ThemeProvider>(context);
//home: const MyHomePage(),
initialRoute: '/splash', return MaterialApp(
routes: { title: 'Task Tracker',
'/splash': (context) => const SplashScreen(), themeMode: themeProvider.themeMode,
'/welcome': (context) => const WelcomePage(), theme: ThemeData(accentColor: Colors.redAccent,brightness: Brightness.light, primaryColor: Colors.amber, fontFamily: 'Noto-Sans'),
'/': (context) => const MyHomePage(), darkTheme: ThemeData(accentColor: Colors.redAccent,brightness: Brightness.dark, primaryColor: Colors.amber, fontFamily: 'Noto-Sans'),
'/Tasks': (context) => const Tasks(), //home: const MyHomePage(),
'/Categories': (context) => const Categories(), initialRoute: '/splash',
'/Activities': (context) => const Activities() routes: {
}); '/splash': (context) => const SplashScreen(),
} '/welcome': (context) => const WelcomePage(),
'/': (context) => const MyHomePage(),
'/Tasks': (context) => const Tasks(),
'/Categories': (context) => const Categories(),
'/Activities': (context) => const Activities(),
'/Settings':(context) => const SettingsPage()
});
});
} }
List<String> days = []; List<String> days = [];
@@ -129,7 +139,7 @@ class _MyHomePageState extends State<MyHomePage> {
void initState() { void initState() {
// TODO: implement initState // TODO: implement initState
super.initState(); super.initState();
User.refreshUserData().then((val) => LoadStats()); // User.refreshUserData().then((val) => LoadStats());
// showOfflineSnack(); // showOfflineSnack();
LoadStats(); LoadStats();
// progressDialog = ProgressDialog(context: context); // progressDialog = ProgressDialog(context: context);
@@ -153,17 +163,18 @@ class _MyHomePageState extends State<MyHomePage> {
firstDay = null; firstDay = null;
lastDay = null; lastDay = null;
String lastDate = ""; String lastDate = "";
days=[];
for (var element in User.activities) { for (var element in User.activities) {
if (lastDay == null) { if (lastDay == null) {
lastDay = element.endTime; lastDay = element.endTime;
} }
if (taskTypeRange == null) { if (taskTypeRange == null) {
print("$lastDay - $firstDay"); print("$lastDay - $firstDay");
taskTypeRange = DateTimeRange(start: lastDay!.subtract(const Duration(days: 1)), end: lastDay!); taskTypeRange = DateTimeRange(start: lastDay!.subtract(const Duration(days: 0)), end: lastDay!);
} }
if (catsRange == null) { if (catsRange == null) {
print("$lastDay - $firstDay"); print("$lastDay - $firstDay");
catsRange = DateTimeRange(start: lastDay!.subtract(const Duration(days: 1)), end: lastDay!); catsRange = DateTimeRange(start: lastDay!.subtract(const Duration(days: 0)), end: lastDay!);
} }
firstDay = element.startTime; firstDay = element.startTime;
String thisDate = dFormat.format(element.startTime); String thisDate = dFormat.format(element.startTime);
@@ -237,7 +248,9 @@ class _MyHomePageState extends State<MyHomePage> {
Color barCol = HexColor.fromHex(key.color); Color barCol = HexColor.fromHex(key.color);
dailyData.add(CatMapData(key.name, value, barCol)); dailyData.add(CatMapData(key.name, value, barCol));
}); });
dailyData.sort((a,b){
return a.name.toLowerCase().compareTo(b.name.toLowerCase());
});
for (var element in days) { for (var element in days) {
// if(productivtyActs.containsKey(element) && unproductivtyActs.containsKey(element)){ // if(productivtyActs.containsKey(element) && unproductivtyActs.containsKey(element)){
int prodActs = (productivtyActs[element] ?? 0); int prodActs = (productivtyActs[element] ?? 0);
@@ -252,11 +265,16 @@ class _MyHomePageState extends State<MyHomePage> {
taskTypesData.add(TaskTypeMapData(key.name, value, HexColor.fromHex(key.cat!.color))); 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) { catBriefMap.forEach((key, value) {
print(key.name + " : $value"); print(key.name + " : $value");
Color barCol = HexColor.fromHex(key.color); Color barCol = HexColor.fromHex(key.color);
catsData.add(CatMapData(key.name, value, barCol)); catsData.add(CatMapData(key.name, value, barCol));
}); });
catsData.sort((a,b)=> a.time.compareTo(b.time));
}); });
} }
} }
@@ -281,7 +299,23 @@ class _MyHomePageState extends State<MyHomePage> {
}, },
label: Text("New Activity"), label: Text("New Activity"),
icon: Icon(Icons.add)), icon: Icon(Icons.add)),
appBar: AppBar(title: Row(children: [Icon(Icons.article_outlined, color: Theme.of(context).primaryColor), SizedBox(width: 10), Text('Summary')])), appBar: AppBar(title: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(children: [Icon(Icons.article_outlined, color: Theme.of(context).primaryColor), SizedBox(width: 10), Text('Summary')]),
Row(children: [
InkWell(
onTap: () {
setState(() {
LoadStats();
});
},
child: Icon(Icons.refresh, size: 30),
)
],)
],
)),
drawer: navDrawer(context, 0), drawer: navDrawer(context, 0),
body: SafeArea( body: SafeArea(
child: SingleChildScrollView( child: SingleChildScrollView(
@@ -362,6 +396,12 @@ class _MyHomePageState extends State<MyHomePage> {
dataSource: productivityData.reversed.toList(), dataSource: productivityData.reversed.toList(),
xValueMapper: (ProductivityMapData sales, _) => sales.day, xValueMapper: (ProductivityMapData sales, _) => sales.day,
yValueMapper: (ProductivityMapData sales, _) => sales.productivity, yValueMapper: (ProductivityMapData sales, _) => sales.productivity,
dataLabelMapper: (ProductivityMapData sales, _) => sales.productivity.toStringAsFixed(1) + "%",
dataLabelSettings: DataLabelSettings(
overflowMode: OverflowMode.hide,
showZeroValue: false,
isVisible: true
),
color: Colors.green) color: Colors.green)
]), ]),
) )
@@ -616,7 +656,12 @@ Drawer navDrawer(BuildContext context, int pageIndex) {
selected: (pageIndex == 5), selected: (pageIndex == 5),
title: Text('Settings'), title: Text('Settings'),
leading: Icon(Icons.settings, color: Colors.blueGrey), leading: Icon(Icons.settings, color: Colors.blueGrey),
onTap: () {}, onTap: () {
if (pageIndex == 5) {
return;
}
Navigator.of(context).pushNamed('/Settings');
},
), ),
ListTile( ListTile(
selected: (pageIndex == 6), selected: (pageIndex == 6),

View File

@@ -1,9 +1,11 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:tasktracker/Data.dart';
import 'User.dart' as Users; import 'User.dart' as Users;
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
import 'package:sn_progress_dialog/sn_progress_dialog.dart'; import 'package:sn_progress_dialog/sn_progress_dialog.dart';
import 'theme_provider.dart';
import 'package:provider/provider.dart';
late ProgressDialog progressDialog; late ProgressDialog progressDialog;
class SplashScreen extends StatefulWidget { class SplashScreen extends StatefulWidget {
const SplashScreen({Key? key}) : super(key: key); const SplashScreen({Key? key}) : super(key: key);
@@ -13,6 +15,18 @@ class SplashScreen extends StatefulWidget {
} }
class _SplashScreenState extends State<SplashScreen> { class _SplashScreenState extends State<SplashScreen> {
Future<void> initSettings() async{
final prefs = await SharedPreferences.getInstance();
bool value = true;
if(prefs.containsKey("theme")){
value = ((await prefs.getInt("theme"))==0);
}else{
await prefs.setInt("theme", 0);
}
print('Dark theme is : $value');
final provider = Provider.of<ThemeProvider>(context, listen: false);
provider.toggleTheme(value);
}
@override @override
void initState() { void initState() {
// TODO: implement initState // TODO: implement initState
@@ -23,6 +37,7 @@ class _SplashScreenState extends State<SplashScreen> {
} }
void init() async { void init() async {
await initSettings();
final prefs = await SharedPreferences.getInstance(); final prefs = await SharedPreferences.getInstance();
// http.Response loginResponse = await Users.login('Test1', 'password'); // http.Response loginResponse = await Users.login('Test1', 'password');
// print(loginResponse.body); // print(loginResponse.body);

12
lib/theme_provider.dart Normal file
View File

@@ -0,0 +1,12 @@
import 'package:flutter/material.dart';
class ThemeProvider extends ChangeNotifier{
ThemeMode themeMode = ThemeMode.dark;
bool get isDarkMode => themeMode == ThemeMode.dark;
void toggleTheme(bool isOn){
themeMode = isOn ? ThemeMode.dark : ThemeMode.light;
notifyListeners();
}
}

View File

@@ -212,6 +212,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.7.0" version: "1.7.0"
nested:
dependency: transitive
description:
name: nested
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
path: path:
dependency: transitive dependency: transitive
description: description:
@@ -289,6 +296,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "4.2.4" version: "4.2.4"
provider:
dependency: "direct main"
description:
name: provider
url: "https://pub.dartlang.org"
source: hosted
version: "6.0.2"
shared_preferences: shared_preferences:
dependency: "direct main" dependency: "direct main"
description: description:
@@ -405,7 +419,7 @@ packages:
name: syncfusion_flutter_charts name: syncfusion_flutter_charts
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "19.4.53" version: "19.4.54"
syncfusion_flutter_core: syncfusion_flutter_core:
dependency: transitive dependency: transitive
description: description:

View File

@@ -30,6 +30,7 @@ dependencies:
flutter: flutter:
sdk: flutter sdk: flutter
provider: ^6.0.2
cupertino_icons: ^1.0.2 cupertino_icons: ^1.0.2
uuid: ^3.0.5 uuid: ^3.0.5
wakelock: ^0.6.1+1 wakelock: ^0.6.1+1