Polishings

This commit is contained in:
warlock
2022-03-07 18:52:36 +05:30
parent f749c4ce8d
commit 455483299f
11 changed files with 461 additions and 230 deletions

View File

@@ -237,7 +237,8 @@ class _ActivitiesState extends State<Activities> {
children: [
Row(
children: [
Icon(Icons.remove_circle_outline),
SizedBox(width: 15,),
Icon(Icons.circle),
SizedBox(
width: 10,
),
@@ -316,7 +317,14 @@ class _ActivitiesState extends State<Activities> {
OnItemSelected(activity);
setState(() {});
})
: Container(padding: EdgeInsets.fromLTRB(10, 0, 5, 0), child: SizedBox(width: 1, height: 100, child: Container(color: Colors.white))),
: Container(padding: EdgeInsets.fromLTRB(10, 0, 5, 0), child: Column(
mainAxisSize: MainAxisSize.max,mainAxisAlignment: MainAxisAlignment.center,
children: [
// Text(dateFormat.format(activity.endTime)),
SizedBox(width: 1, height: 100, child: Container(color: Colors.white)),
Text(dateFormat.format(activity.startTime)),
],
)),
Expanded(
child: Column(children: [
Padding(

View File

@@ -108,6 +108,7 @@ class Settings{
static String notification_key= "notification_interval";
static String adaptive_notification_key = "adaptive_notification";
static String untracked_unprod_key = "untracked_unproductive";
static Future<int> getNotificationInterval() async{
final prefs = await SharedPreferences.getInstance();
@@ -161,5 +162,23 @@ class Settings{
final prefs = await SharedPreferences.getInstance();
prefs.setBool(adaptive_notification_key, value);
}
static Future<bool> getUntrackedUnproductive() async{
final prefs = await SharedPreferences.getInstance();
bool _value = true;
if(prefs.containsKey(untracked_unprod_key)){
_value = await prefs.getBool(untracked_unprod_key) ?? true;
}else{
prefs.setBool(untracked_unprod_key,_value);
}
return _value;
}
static Future<void> setUntrackedUnproductive(bool value) async{
final prefs = await SharedPreferences.getInstance();
prefs.setBool(untracked_unprod_key, value);
}
}
final settings = Settings();

View File

@@ -96,11 +96,13 @@ class NotificationManager{
}
await Future.delayed(Duration(seconds: 2));
final List<PendingNotificationRequest> pendingNotificationRequests =await fltrNotification.pendingNotificationRequests();
try{ final List<PendingNotificationRequest> pendingNotificationRequests =await fltrNotification.pendingNotificationRequests();
print("Notifications");
pendingNotificationRequests.forEach((element) {
print("${element.id} : ${element.title} -> ${element.body} \n payload:${element.payload}");
});
});}catch(e){
print("Error printing notifications \n $e");
}
}
static void notificationSelected(val){

View File

@@ -0,0 +1,57 @@
import 'package:flutter/material.dart';
import 'package:tasktracker/Settings/Settings.dart';
import 'package:tasktracker/Data.dart';
class BehaviourSettings extends StatefulWidget {
const BehaviourSettings({Key? key}) : super(key: key);
@override
_BehaviourSettingsState createState() => _BehaviourSettingsState();
}
class _BehaviourSettingsState extends State<BehaviourSettings> {
bool untracked_unprod = true;
@override void initState() {
// TODO: implement initState
super.initState();
init();
}
void init() async{
untracked_unprod=await Settings.getUntrackedUnproductive();
setState(() {
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Behaviour Settings')),
body: SafeArea(
child: Container(
child:Column(
children: [
ListTile(
title:Text("Count untracked time as unproductive"),
subtitle: Text("Not tracking = Not productive"),
trailing: Switch.adaptive(value: untracked_unprod, onChanged: (val){
untracked_unprod=val;
setState(() {
Settings.setUntrackedUnproductive(val);
});
setState(() {
});
}),
),
],
)
),
)
);
}
}

View File

@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:tasktracker/Settings/AppearanceSettings.dart';
import 'package:tasktracker/Settings/NotificationSettings.dart';
import 'package:tasktracker/Settings/BehaviourSettings.dart';
import 'package:tasktracker/main.dart';
class SettingsPage extends StatefulWidget {
@@ -18,9 +19,33 @@ class _SettingsPageState extends State<SettingsPage> {
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()))),
ListTile(
title: Text('Appearance'),
subtitle: Text('Just the looks and feels'),
trailing: Icon(Icons.arrow_forward_ios),
onTap: (){
Navigator.of(context).push(MaterialPageRoute(builder: (context)=> const AppearanceSettings()));
},
),
ListTile(
title: Text('Notifications'),
subtitle: Text("Don't worry, We won't let you forget"),
trailing: Icon(Icons.arrow_forward_ios),
onTap: (){
Navigator.of(context).push(MaterialPageRoute(builder: (context)=> const NotificationSettings()));
},
),
ListTile(
title:Text("General Behaviour"),
subtitle: Text("Wanna change how the app works? Go ahead!"),
trailing: Icon(Icons.arrow_forward_ios),
onTap: (){
Navigator.of(context).push(MaterialPageRoute(builder: (context)=> const BehaviourSettings()));
},
)
// SettingItem('Appearance', ()=>Navigator.of(context).push(MaterialPageRoute(builder: (context)=> const AppearanceSettings()))),
// Divider(),
// SettingItem('Notifications', ()=>Navigator.of(context).push(MaterialPageRoute(builder: (context)=> const NotificationSettings()))),
],
)
);

82
lib/Todo.dart Normal file
View File

@@ -0,0 +1,82 @@
import 'package:flutter/material.dart';
import 'User.dart' as User;
import 'main.dart';
class TodoPage extends StatefulWidget {
const TodoPage({Key? key}) : super(key: key);
@override
State<TodoPage> createState() => _TodoPageState();
}
class _TodoPageState extends State<TodoPage> {
@override
Widget build(BuildContext context) {
return SafeArea(child: Scaffold(
floatingActionButton: FloatingActionButton.extended(
onPressed: () {
// Navigator.of(context).push(MaterialPageRoute(builder: (context) => NewActivity())).then((value) => {User.refreshUserData().then((va) => LoadStats())});
},
label: Text("New Todo"),
icon: Icon(Icons.add)),
appBar: AppBar(
title: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.end,
children: [
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(children: [Icon(Icons.check, color: Theme.of(context).primaryColor), SizedBox(width: 10), Text('Todo')]),
Row(
children: [
(User.offline)
? Icon(Icons.signal_cellular_connected_no_internet_4_bar_outlined)
: InkWell(
onTap: () {
setState(() {
//LoadStats();
});
},
child: Icon(Icons.refresh, size: 30),
)
],
)
],
),
//Container(color: Colors.red,child: Text("Offline",style:TextStyle(fontSize: 5))),
],
)),
drawer: navDrawer(context, 7),
body: Column(
children: PrintTodos(),
),
));
}
List<Widget> PrintTodos(){
List<Widget> todos = [];
todos.forEach((element) {
});
todos.add(prioritySeperator('- High Priority (0)'));
todos.add(prioritySeperator('- Low Priority (0)'));
return todos;
}
Widget todoItem(String name){
return Row(children:[Text(name)]);
}
Widget prioritySeperator(String text){
return Padding(
padding: const EdgeInsets.fromLTRB(15,15,15,0),
child: Row(
children: [Text(text,style:TextStyle(fontSize: 18, color: Colors.grey))],
),
);
}
}

View File

@@ -6,7 +6,6 @@ import 'package:flutter/cupertino.dart';
import 'package:intl/intl.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:tasktracker/NotificationsManager.dart';
import 'main.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
@@ -14,11 +13,13 @@ import 'Data.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path_provider/path_provider.dart';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:sqflite_common/sqlite_api.dart';
import 'package:sqflite_common_ffi/sqflite_ffi.dart' as SqlFF;
import 'Tasks.dart';
late http.Response loginResponse;
late Database cacheDb;
late var cacheDb;
late String username;
List<Category> categories = [];
List<TaskType> taskTypes = [];
@@ -72,8 +73,13 @@ Future<void> refreshUserData() async {
NotificationManager.RescheduleNotifications();
}
Future<bool> cacheDbExist() async {
Directory directory = await getApplicationDocumentsDirectory();
return databaseFactory.databaseExists(directory.path + 'cache.db');
if(Platform.isAndroid || Platform.isIOS){
Directory directory = await getApplicationDocumentsDirectory();
return databaseFactory.databaseExists(directory.path + 'cache.db');
}else{
Directory directory = await getApplicationDocumentsDirectory();
return SqlFF.databaseFactoryFfi.databaseExists(directory.path + 'cache.db');
}
}
Future<void> updateCatsList() async {
@@ -100,8 +106,11 @@ Future<void> updateActList() async {
Future<void> initCacheDatabase() async {
Directory directory = await getApplicationDocumentsDirectory();
print('database at ' + directory.path + 'cache.db');
cacheDb = await openDatabase(directory.path + 'cache.db', version: 1, onCreate: onCacheDatabaseCreate, onUpgrade: onCacheDatabaseUpgrade);
if(Platform.isAndroid || Platform.isIOS) {
cacheDb = await openDatabase(directory.path + 'cache.db', version: 1, onCreate: onCacheDatabaseCreate, onUpgrade: onCacheDatabaseUpgrade);
}else{
cacheDb = await SqlFF.databaseFactoryFfi.openDatabase(directory.path + 'cache.db', options: OpenDatabaseOptions(version: 1,onCreate:onCacheDatabaseCreate ));
}
await UserOperations.executeQueries();
}

View File

@@ -5,6 +5,7 @@ import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
import 'package:tasktracker/Categories.dart';
import 'package:tasktracker/Todo.dart';
import 'package:tasktracker/Welcome.dart';
import 'package:tasktracker/splash.dart';
import 'package:tasktracker/theme_provider.dart';
@@ -93,7 +94,8 @@ class MyApp extends StatelessWidget {
'/Tasks': (context) => const Tasks(),
'/Categories': (context) => const Categories(),
'/Activities': (context) => const Activities(),
'/Settings': (context) => const SettingsPage()
'/Settings': (context) => const SettingsPage(),
'/Todo':(context)=> const TodoPage()
});
});
}
@@ -205,6 +207,9 @@ class _MyHomePageState extends State<MyHomePage> {
firstDay = element.startTime;
String thisDate = dFormat.format(element.startTime);
int thisMinutes = element.endTime.difference(element.startTime).inMinutes;
if(element.startTime.day != element.endTime.day){
print("welp, ${element.startTime} - ${element.endTime}");
}
if (!days.contains(thisDate)) {
days.add(dFormat.format(element.startTime));
}

View File

@@ -44,231 +44,240 @@ class _NewActivity extends State<NewActivity> {
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SingleChildScrollView(
child: Padding(
padding: EdgeInsets.fromLTRB(20, 50, 20, 50),
child: Column(
children: [
Column(children: [
Container(
padding: EdgeInsets.all(10),
child: Text('Task')),
Container(
padding: EdgeInsets.symmetric(
horizontal: 12, vertical: 1),
decoration: BoxDecoration(
color: Colors.blueGrey,
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: Colors.grey, width: 2)),
child: DropdownButton<String>(
dropdownColor: Colors.blueGrey,
iconSize: 30,
elevation: 10,
borderRadius: BorderRadius.circular(10),
value: selectedCat,
isExpanded: true,
items: getActivities().map<DropdownMenuItem<String>>(
(String value) {
print(value);
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
onChanged: (String? _value) {
setState(() {
selectedCat = _value ?? 'n/a';
});
})),
Expanded(
flex: 9,
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Expanded(
child: Padding(
padding: EdgeInsets.fromLTRB(20, 50, 20, 50),
child: Column(
children: [
Column(children: [
Container(
padding: EdgeInsets.all(10),
child: Text('Task')),
Container(
padding: EdgeInsets.all(10),
child:Column(
children: [
Container(
padding: EdgeInsets.symmetric(
horizontal: 12, vertical: 1),
decoration: BoxDecoration(
color: Colors.blueGrey,
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: Colors.grey, width: 2)),
child: DropdownButton<String>(
dropdownColor: Colors.blueGrey,
iconSize: 30,
elevation: 10,
borderRadius: BorderRadius.circular(10),
value: selectedCat,
isExpanded: true,
items: getActivities().map<DropdownMenuItem<String>>(
(String value) {
print(value);
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
onChanged: (String? _value) {
setState(() {
selectedCat = _value ?? 'n/a';
});
})),
TextField(
controller: metadataController,
decoration: InputDecoration(
hintText: 'Description (optional)',
filled: true,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20)
)
),
Container(
padding: EdgeInsets.all(10),
child:Column(
children: [
TextField(
controller: metadataController,
decoration: InputDecoration(
hintText: 'Description (optional)',
filled: true,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20)
)
),
),
],
)
),
Container(
child: Divider(
height: 30,
)),
Container(
padding: EdgeInsets.all(10),
child: Text('Start Time')),
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
QuickTimeButton('Last', Function: (){
if(User.activities.length > 0) {
startTime= User.activities[0].endTime;
}
})
,
Container(
padding: EdgeInsets.symmetric(
horizontal: 12, vertical: 1),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: Colors.grey, width: 2)),
child: MaterialButton(
onPressed: () {
setState(() {
DatePicker.showDateTimePicker(
context,
showTitleActions: true,
onChanged: (date) {
// print('change $date');
}, onConfirm: (date) {
setState(() {
if(endTime.compareTo(date) < 0){
const snackBar = SnackBar(
content: Text('You cannot start something after you ended it!'),
);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}else {
startTime = date;
}
});
},
currentTime: startTime,
locale: LocaleType.en);
});
},
child: Text(
dateFormat.format(startTime),
style: TextStyle(
color: Colors.blue)))),
QuickTimeButton('Now', Function: (){
startTime = DateTime.now();
})
],
),
SizedBox(
height: 10,
),
Container(
padding: EdgeInsets.all(10),
child: Text('Ended Time')),
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Container(width: 60,),
Container(
padding: EdgeInsets.symmetric(
horizontal: 12, vertical: 1),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: Colors.grey, width: 2)),
child: MaterialButton(
onPressed: () {
setState(() {
DatePicker.showDateTimePicker(
context,
showTitleActions: true,
onChanged: (date) {
// print('change $date');
}, onConfirm: (date) {
setState(() {
if(startTime.compareTo(date) > 0){
const snackBar = SnackBar(
content: Text('You cannot end something before you start it!'),
);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}else {
endTime = date;
}
});
},
currentTime: endTime,
locale: LocaleType.en);
});
},
child: Text(dateFormat.format(endTime),
style: TextStyle(
color: Colors.blue)))),
QuickTimeButton('Now', Function: (){
endTime = DateTime.now();
})
],
),
SizedBox(
height: 30,
),
Text('Duration : ' +
_printDuration(
endTime.difference(startTime)),
style:TextStyle(
fontSize: 20,
)),
Divider(
height: 30,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
],
)
]),
],
)),
)),
),
Expanded(
flex: 1,
child: Container(
padding:
EdgeInsets.symmetric(vertical: 10, horizontal: 20),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Expanded(
flex: 5,
child: Container(
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 0),
child: ElevatedButton(
style:ElevatedButton.styleFrom(
primary: Colors.red,
shape: StadiumBorder()
),
],
)
),
Container(
child: Divider(
height: 30,
)),
Container(
padding: EdgeInsets.all(10),
child: Text('Start Time')),
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
QuickTimeButton('Last', Function: (){
if(User.activities.length > 0) {
startTime= User.activities[0].endTime;
}
})
,
Container(
padding: EdgeInsets.symmetric(
horizontal: 12, vertical: 1),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: Colors.grey, width: 2)),
child: MaterialButton(
onPressed: () {
setState(() {
DatePicker.showDateTimePicker(
context,
showTitleActions: true,
onChanged: (date) {
// print('change $date');
}, onConfirm: (date) {
setState(() {
if(endTime.compareTo(date) < 0){
const snackBar = SnackBar(
content: Text('You cannot start something after you ended it!'),
);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}else {
startTime = date;
}
});
},
currentTime: startTime,
locale: LocaleType.en);
});
},
child: Text(
dateFormat.format(startTime),
style: TextStyle(
color: Colors.blue)))),
QuickTimeButton('Now', Function: (){
startTime = DateTime.now();
})
],
),
SizedBox(
height: 10,
),
Container(
padding: EdgeInsets.all(10),
child: Text('Ended Time')),
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Container(width: 60,),
Container(
padding: EdgeInsets.symmetric(
horizontal: 12, vertical: 1),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: Colors.grey, width: 2)),
child: MaterialButton(
onPressed: () {
setState(() {
DatePicker.showDateTimePicker(
context,
showTitleActions: true,
onChanged: (date) {
// print('change $date');
}, onConfirm: (date) {
setState(() {
if(startTime.compareTo(date) > 0){
const snackBar = SnackBar(
content: Text('You cannot end something before you start it!'),
);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}else {
endTime = date;
}
});
},
currentTime: endTime,
locale: LocaleType.en);
});
},
child: Text(dateFormat.format(endTime),
style: TextStyle(
color: Colors.blue)))),
QuickTimeButton('Now', Function: (){
endTime = DateTime.now();
})
],
),
SizedBox(
height: 30,
),
Text('Duration : ' +
_printDuration(
endTime.difference(startTime)),
style:TextStyle(
fontSize: 20,
)),
Divider(
height: 30,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
],
)
]),
],
))),
Container(
padding:
EdgeInsets.symmetric(vertical: 10, horizontal: 20),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Expanded(
flex: 5,
onPressed: () {
Navigator.pop(context);
},
child: Text('Back',
style: TextStyle(fontSize: 20))))),
Expanded(
flex: 6,
child: Container(
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 0),
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 0),
child: ElevatedButton(
style:ElevatedButton.styleFrom(
primary: Colors.red,
primary: Colors.green,
shape: StadiumBorder()
),
onPressed: () {
Navigator.pop(context);
},
child: Text('Back',
style: TextStyle(fontSize: 20))))),
Expanded(
flex: 6,
child: Container(
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 0),
child: ElevatedButton(
style:ElevatedButton.styleFrom(
primary: Colors.green,
shape: StadiumBorder()
),
onPressed: () {
onPressed: () {
add_action();
},
child: Text('Add Entry',
style: TextStyle(fontSize: 20))))),
],
))
add_action();
},
child: Text('Add Entry',
style: TextStyle(fontSize: 20))))),
],
)),
)
])));
}

View File

@@ -490,6 +490,20 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.0"
sqflite_common_ffi:
dependency: "direct main"
description:
name: sqflite_common_ffi
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0+2"
sqlite3:
dependency: transitive
description:
name: sqlite3
url: "https://pub.dartlang.org"
source: hosted
version: "1.5.1"
stack_trace:
dependency: transitive
description:

View File

@@ -30,6 +30,7 @@ dependencies:
flutter:
sdk: flutter
sqflite_common_ffi: ^2.1.0+2
connectivity_plus: ^2.2.1
flutter_spinkit: ^5.1.0
flutter_local_notifications: ^9.3.3