From 4335ce43db768558dd049432955991053251e6e8 Mon Sep 17 00:00:00 2001 From: Sewmina Date: Tue, 29 Mar 2022 21:36:11 +0530 Subject: [PATCH] Journal section added --- lib/Activities.dart | 90 +++++++++++++----- lib/Data.dart | 13 +++ lib/Journal.dart | 165 +++++++++++++++++++++++++++++++++ lib/NewJournal.dart | 189 +++++++++++++++++++++++++++++++++++++ lib/User.dart | 220 +++++++++++++++++++++++++++++++++++++++++++- lib/main.dart | 50 ++++------ pubspec.lock | 7 ++ pubspec.yaml | 1 + 8 files changed, 673 insertions(+), 62 deletions(-) create mode 100644 lib/Journal.dart create mode 100644 lib/NewJournal.dart diff --git a/lib/Activities.dart b/lib/Activities.dart index c2de589..c5ea3dd 100644 --- a/lib/Activities.dart +++ b/lib/Activities.dart @@ -1,11 +1,13 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_datetime_picker/flutter_datetime_picker.dart'; import 'package:intl/intl.dart'; import 'package:sticky_headers/sticky_headers/widget.dart'; import 'main.dart' as Main; import 'newActivity.dart'; import 'Data.dart'; import 'User.dart' as User; +import 'package:scrollable_positioned_list/scrollable_positioned_list.dart'; class Activities extends StatefulWidget { const Activities({Key? key}) : super(key: key); @@ -66,7 +68,7 @@ class _ActivitiesState extends State { // progressDialog.update(value: 100); } catch (e) {} } - Map> activitiesGroups =>{}; + Map activitiesGroups = {}; @override Widget build(BuildContext context) { // progressDialog = ProgressDialog(context: context); @@ -172,14 +174,15 @@ class _ActivitiesState extends State { drawer: Main.navDrawer(context, 2), body: Container( padding: EdgeInsets.all(0), - child: ListView.builder( + child: ScrollablePositionedList.builder( + itemScrollController: scrollController, itemCount: activitiesGroups.length, itemBuilder: (context, index){ // return activities[index]; return StickyHeader( - header:activitiesGroups.keys.toList()[index], - content:Column(children: activitiesGroups.values.toList()[index],) + header:activitiesGroups.values.toList()[index].dateSeperator, + content:Column(children: activitiesGroups.values.toList()[index].activities,) ); }) @@ -189,13 +192,17 @@ class _ActivitiesState extends State { // )) )); } - + DateFormat dFormat = DateFormat("yyyy-MM-dd"); + ItemScrollController scrollController = ItemScrollController(); + ScrollController controller = ScrollController(); int searchTime = 0; - Map> PrintTasks() { - Map> _tasks = >{}; + Map PrintTasks() { + + Map _tasks = {}; + print('Priting cats : ' + User.taskTypes.length.toString()); String lastDate = ""; - DateFormat dFormat = DateFormat("MM/dd"); + Map productivtyActs = {}; Map unproductivtyActs = {}; Map totalMinutes = {}; @@ -248,7 +255,8 @@ class _ActivitiesState extends State { int prodActs = productivtyActs[thisDate] ?? 0; int unProdActs = unproductivtyActs[thisDate] ?? 0; //_tasks.add(DateSeperator(thisDate, prodActs, unProdActs)); - _tasks.putIfAbsent(DateSeperator(thisDate, prodActs, unProdActs), () => [Container()]); + // _tasks.putIfAbsent(DateSeperator(thisDate, prodActs, unProdActs), () => [List.generate(0, (i) => List(2));]); + _tasks.putIfAbsent(thisDate, () => ActivityListDateGroup(DateSeperator(thisDate, prodActs, unProdActs), [])); print('adding'); lastDate = thisDate; } @@ -260,7 +268,8 @@ class _ActivitiesState extends State { bool productive = element.taskType.cat?.productive ?? true; Widget task = ActivityCard(context, name, element.startTime, element.endTime, productive, color, element, totalMinutes[thisDate] ?? 0); // print('Activity : ${name} ,sTime: ${element.startTime}, eTime: ${element.endTime}'); - _tasks.values.toList()[_tasks.length-1].add(task); + // _tasks.values.toList()[_tasks.length-1].add(task); + _tasks[thisDate]!.activities.add(task); } //Check for gaps if(i < User.activities.length-1){ @@ -268,7 +277,8 @@ class _ActivitiesState extends State { if(gap > 10) { Widget addGap = timeGap(User.activities[i].trueStartTime, User.activities[i+1].trueEndTime); - _tasks.values.toList()[_tasks.length-1].add(addGap); + //_tasks.values.toList()[_tasks.length-1].add(addGap); + _tasks[thisDate]!.activities.add(addGap); } } } @@ -320,7 +330,22 @@ class _ActivitiesState extends State { ); } - Widget DateSeperator(date, prodActs, unprodActs) { + void OnJumpToDate(date){ + int itemId = 0; + List keys = activitiesGroups.keys.toList(); + List values = activitiesGroups.values.toList(); + for(int i =0; i < activitiesGroups.length; i++){ + + if(keys[i] == dFormat.format(date)){ + break; + } + itemId++; + // itemId+= values[i].activities.length; + } + scrollController.scrollTo(index: itemId, duration: Duration(seconds: 1),curve: Curves.fastOutSlowIn); + } + + Widget DateSeperator(date, prodActs, unprodActs,{Function? onTap}) { // double prodPercentage = (prodActs / (prodActs + unprodActs)) * 100; return FutureBuilder( @@ -337,18 +362,29 @@ class _ActivitiesState extends State { mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Row( - children: [ - SizedBox(width: 15,), - Icon(Icons.circle), - SizedBox( - width: 10, - ), - Text( - date, - style: TextStyle(fontSize: 18), - ), - ], + InkWell( + onTap: (){ + DatePicker.showDatePicker(context, + showTitleActions: true, + minTime: User.activities[User.activities.length-1].startTime, + maxTime: User.activities[0].startTime, + theme: DatePickerTheme(), onChanged: (date) { + // print('change $date'); + }, onConfirm: OnJumpToDate, currentTime: DateTime.parse(date), locale: LocaleType.en); + }, + child: Row( + children: [ + SizedBox(width: 15,), + Icon(Icons.circle), + SizedBox( + width: 10, + ), + Text( + date, + style: TextStyle(fontSize: 18), + ), + ], + ), ), Row( children: [ @@ -550,5 +586,11 @@ class _ActivitiesState extends State { } } +class ActivityListDateGroup{ + ActivityListDateGroup(this.dateSeperator, this.activities); + Widget dateSeperator; + List activities; +} + List selectedActivities = []; diff --git a/lib/Data.dart b/lib/Data.dart index 85d7656..0c8e35c 100644 --- a/lib/Data.dart +++ b/lib/Data.dart @@ -142,6 +142,19 @@ class ProjectStep{ DateTime? finishedDate; } +class Journal{ + + Journal(this.id, this.day, {this.title, this.description}); + + String id; + DateTime day; + String? title; + String? description; + + static String colTitle = 'Title'; + static String colDescription = 'Desc'; +} + diff --git a/lib/Journal.dart b/lib/Journal.dart new file mode 100644 index 0000000..a9dbd57 --- /dev/null +++ b/lib/Journal.dart @@ -0,0 +1,165 @@ +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:flutter/material.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; +import 'package:intl/intl.dart'; +import 'package:scrollable_positioned_list/scrollable_positioned_list.dart'; +import 'package:tasktracker/NewJournal.dart'; +import 'package:tasktracker/main.dart'; +import 'User.dart' as User; +import 'Dialogs.dart'; + +class JournalPage extends StatefulWidget { + const JournalPage({Key? key}) : super(key: key); + + @override + State createState() => _JournalPageState(); +} + +class _JournalPageState extends State { + + bool selecting = false; + List selectedIndexes = []; + var refreshStream; + @override + void initState() { + // TODO: implement initState + super.initState(); + + refreshStream = User.refreshStream.stream.listen((event) {if(!event){setState(() { + + });}}); + } + + @override + void dispose() { + // TODO: implement dispose + super.dispose(); + refreshStream?.close(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + floatingActionButton: FloatingActionButton.extended( + onPressed: () { + Navigator.of(context).push(MaterialPageRoute(builder: (context) => NewJournal())).then((val) { + setState(() {}); + }); + }, + label: Text("New Entry"), + icon: Icon(Icons.add)), + appBar: AppBar( + title: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + FaIcon(FontAwesomeIcons.bookJournalWhills), + SizedBox( + width: 15, + ), + Text('Journal') + ], + ), + Row( + children: [ + if(selecting && selectedIndexes.length > 0)InkWell(onTap:() async{ + selecting=false; + for (int element in selectedIndexes) { + await User.UserOperations.deleteJournal(User.journal[element].id); + }setState(() { + + }); + },child: Container(margin:EdgeInsets.all(8),child: Icon(Icons.delete))), + if(selecting)InkWell(onTap:(){ + selecting=false; + setState(() { + + }); + },child: Container(margin:EdgeInsets.all(8),child: Icon(Icons.cancel))), + ], + ) + ], + ), + ), + drawer: navDrawer(context, 8), + body: Container( + padding: EdgeInsets.all(8), + child: ScrollablePositionedList.builder( + itemCount: User.journal.length, + itemBuilder: (context, index) { + return Container( + + //duration: Duration(milliseconds: 500), + child: InkWell( + onTap: (){ + if(selecting){ + if(selectedIndexes.contains(index)){ + selectedIndexes.remove(index); + }else{ + selectedIndexes.add(index); + } + setState(() { + + }); + } + }, + onLongPress: () { + selecting = !selecting; + if(!selectedIndexes.contains(index)){selectedIndexes.add(index);} + setState(() {}); + }, + child: Row( + children: [ + if (selecting) + Checkbox( + value: selectedIndexes.contains(index), + onChanged: (newVal) { + if(selectedIndexes.contains(index)){ + selectedIndexes.remove(index); + }else{ + selectedIndexes.add(index); + } + setState(() { + + }); + }, + ), + Expanded( + child: Card( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text(User.journal[index].title ?? '', style: TextStyle(fontSize: 18)), + Text(DateFormat('yyyy-MM-dd').format(User.journal[index].day)) + ], + ), + if (User.journal[index].description != null && User.journal[index].description!.isNotEmpty) + Text(User.journal[index].description!) + ], + ), + ), + ), + ), + if(selecting)InkWell(onTap:(){ + Navigator.of(context).push(MaterialPageRoute(builder: (context) => NewJournal(date: User.journal[index].day, title: User.journal[index].title, text: User.journal[index].description,))).then((val) { + setState(() {}); + }); + selecting=false; + setState(() { + + }); + },child: Container(margin:EdgeInsets.all(8),child: FaIcon(FontAwesomeIcons.edit))) + ], + ), + )); + }), + ), + ); + } +} diff --git a/lib/NewJournal.dart b/lib/NewJournal.dart new file mode 100644 index 0000000..4a84ee7 --- /dev/null +++ b/lib/NewJournal.dart @@ -0,0 +1,189 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_datetime_picker/flutter_datetime_picker.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; +import 'package:intl/intl.dart'; +import 'package:flutter_colorpicker/flutter_colorpicker.dart'; +import 'User.dart' as User; +import 'Data.dart'; + +class NewJournal extends StatefulWidget { + NewJournal({Key? key, this.title, this.text, this.date}) : super(key: key); + late String? title; + late String? text; + late DateTime? date; + + @override + _NewJournalState createState() => _NewJournalState(title: title, text: text, m_date: date); +} + +class _NewJournalState extends State { + bool editing =false; + _NewJournalState({String? title, String? text, DateTime? m_date}){ + if(m_date!= null){ + editing = true; + date=m_date; + oldDate =m_date; + } + + titleController.text = title??''; + descriptionEditingController.text = text??''; + } + + TextEditingController titleController = TextEditingController(); + TextEditingController descriptionEditingController = TextEditingController(); + bool productive = true; + Color pickerColor = Colors.blue; + DateTime date= DateTime.now(); + DateTime oldDate = DateTime.now(); + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: Text('${(editing) ? 'Edit' : 'New'} Journal Entry')), + body: Container( + height: MediaQuery.of(context).size.height, + child: Column(mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ + Expanded(flex: 9, + child: SingleChildScrollView( + child: Padding( + padding: EdgeInsets.fromLTRB(20, 50, 20, 50), + child: Column( + children: [ + InkWell( + onTap: (){ + DatePicker.showDatePicker(context, + showTitleActions: true, + minTime: User.activities[User.activities.length-1].startTime, + maxTime: User.activities[0].startTime, + theme: DatePickerTheme(), onChanged: (date) { + // print('change $date'); + }, onConfirm: (newDate){ + date = newDate; + }, currentTime: DateTime.now(), locale: LocaleType.en); + }, + child: Container( + margin: EdgeInsets.symmetric(vertical: 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + FaIcon(FontAwesomeIcons.calendarDay), + SizedBox(width: 10,), + Text('Date : '), + SizedBox(width: 30,), + Text( + DateFormat('yyyy-MM-dd').format(date), + style: TextStyle(fontSize: 18), + ), + SizedBox(width: 30,), + ], + ), + ), + ), + SizedBox(height: 10,), + Column(children: [ + Container( + padding: EdgeInsets.all(10), + child: TextField( + controller: titleController, + decoration: InputDecoration(hintText: 'Title (something special happened this day)', border: OutlineInputBorder()), + ), + ), + Divider(), + Container( + padding: EdgeInsets.all(10), + child: TextField( + + maxLines: 25, + minLines: 10, + controller: descriptionEditingController, + decoration: InputDecoration(hintText: 'So how was your day? Write it all down here!', border: OutlineInputBorder()), + ), + ), + ]), + ], + ))), + ), + 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()), + onPressed: () { + setState(() { + 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: () { + add_action(); + }, + child: Text('${editing ? 'Edit ' : 'Add '}Entry', style: TextStyle(fontSize: 20))))), + ], + )) + ]))); + } + + void add_action() async { + String title = titleController.value.text; + String text = descriptionEditingController.text; + + if (title.isEmpty && text.isEmpty) { + showAlertDialog(context, 'Empty data', 'Journal entry is empty, Cannot add empty entries'); + return; + } + if(editing){ + await User.UserOperations.editJournal(oldDate,date,title,text); + }else{ + await User.UserOperations.addJournal(date, title, text); + } + Navigator.of(context).popUntil((route) { + return route.isFirst; + }); + } +} + +String _printDuration(Duration duration) { + String twoDigits(int n) => n.toString().padLeft(2, "0"); + String twoDigitMinutes = twoDigits(duration.inMinutes.remainder(60)); + String twoDigitSeconds = twoDigits(duration.inSeconds.remainder(60)); + return "${twoDigits(duration.inHours)}:$twoDigitMinutes:$twoDigitSeconds"; +} + +showAlertDialog(BuildContext context, String title, String message) { + // set up the button + Widget okButton = TextButton( + child: Text("OK"), + onPressed: () { + Navigator.of(context).pop(); + }, + ); + + // set up the AlertDialog + AlertDialog alert = AlertDialog( + title: Text(title), + content: Text(message), + actions: [ + okButton, + ], + ); + + // show the dialog + showDialog( + context: context, + builder: (BuildContext context) { + return alert; + }, + ); +} diff --git a/lib/User.dart b/lib/User.dart index 1d99272..869a44c 100644 --- a/lib/User.dart +++ b/lib/User.dart @@ -28,6 +28,7 @@ List categories = []; List taskTypes = []; List activities = []; List projects = []; +List journal = []; bool offline = true; bool registered = false; @@ -136,14 +137,17 @@ Future refreshUserData({bool forceOffline = false}) async { taskTypes = await GetTaskTypes(true); activities = await GetActivities(true); projects= await GetProjects(true); + journal = await GetJournals(true); refreshStream.add(false); }else{ - await updateCatsList(); - await updateTasksList(); - await updateActList(); - await updateProjectsList(); + categories = await GetCategories(false); + taskTypes = await GetTaskTypes(false); + activities = await GetActivities(false); + projects= await GetProjects(false); + journal = await GetJournals(false); + } m_refreshing=false; @@ -213,6 +217,8 @@ void onCacheDatabaseCreate(Database db, int newVersion) async { 'CREATE TABLE Projects(id TEXT PRIMARY KEY, ${Project.colName} TEXT, ${Project.colCat} TEXT, ${Project.colSteps} TEXT, ${Project.colEta} INT, ${Project.colDeadline} DATETIME)'; await db.execute(ProjectsTableSQL); + String JournalTableSQL = 'CREATE TABLE Journal(id TEXT PRIMARY KEY, ${Journal.colTitle} TEXT, ${Journal.colDescription})'; + await db.execute(JournalTableSQL); String QueriesTableSQL = 'CREATE TABLE Queries(id INTEGER PRIMARY KEY AUTOINCREMENT, ${Queries.colLink} TEXT,${Queries.colData} TEXT)'; // print(QueriesTableSQL); await db.execute(QueriesTableSQL); @@ -750,6 +756,92 @@ Future UpdateProjectsFromServer() async { } } +Future> GetJournals(bool forceOffline) async { + if (cacheEnabled) { + List _journals = []; + if (offline || forceOffline) { + //Retreive from cacheDB + + } else { + //Check if server got updated, If not go for cache + + //Validate device_id to check updates + + bool catsUpdated = false; + // try { + // http.Response update_response = (await http.post(Uri.parse('http://161.97.127.136/task_tracker/check_update.php'), body: {"username": username, "device_id": android_id})); + // final data = update_response.body.split(','); + // catsUpdated = data[0] == '1'; + // } catch (e) { + // print(e); + // } + + //Update CacheDB + if (!catsUpdated) { + await UpdateJournalsFromServer(); + } + } + + List cats = await cacheDb.query('Journal'); + print(cats.length); + for (Map element in cats) { + String? id = element['id'].toString(); + String? title = element[Journal.colTitle].toString(); + String? text = element[Journal.colDescription].toString(); + if (id == null || title == null || text == null) { + print("Something is null!"); + print("id:{$id}, title:{$title}, text:${text}"); + continue; + } + DateTime day = DateTime.parse(id.replaceAll(username, '')); + // print("name:{$catName}, color:{$catColor}, prod:{$catProductive}"); + _journals.add(Journal(id,day,title: title,description: text)); + } + journal = _journals; + } else { + print("NC: Updating Categories as $username"); + try { + http.Response response = (await http.post(Uri.parse('http://161.97.127.136/task_tracker/get_journals.php'), + body: {"username": username, "device_id": await Settings.UUID()})); + + print(response.body); + List data = response.body.split(""); + List _categories = []; + for (var value in data) { + Map cat = jsonDecode(value); + //print(catData); + _categories.add(Journal(cat['id'],DateTime.parse(cat['id'].toString().replaceAll(username, '')), title:cat['title'], description:cat['text'])); + } + journal = _categories; + } catch (e) { + print("Error while cats NC: $e"); + } + } + journal.sort((a,b)=> b.day.compareTo(a.day)); + return journal; +} + +Future UpdateJournalsFromServer() async { + print("Updating Journal as $username"); + try { + http.Response response = (await http.post(Uri.parse('http://161.97.127.136/task_tracker/get_journals.php'), + body: {"username": username, "device_id": await Settings.UUID()})); + + print(response.body); + List data = response.body.split(""); + await cacheDb.delete("Journal"); + for (var value in data) { + Map cat = jsonDecode(value); + //print(catData); + await cacheDb + .rawInsert("INSERT OR REPLACE INTO Journal (id, ${Journal.colTitle},${Journal.colDescription}) " + "VALUES ('${cat['id']}','${cat['title'].toString().replaceAll("'", "''")}','${cat['description'].toString().replaceAll("'", "''")}') "); + } + } catch (e) { + print("Error while cats $e"); + } +} + Future getTaskFromId(String taskId) async { // await GetTaskTypes(false); TaskType? cat = null; @@ -1221,6 +1313,89 @@ class UserOperations { await executeQueries(); } + static Future addJournal(DateTime day, String title, String text) async { + String id = username + DateFormat('yyyy-MM-dd').format(day); + Map queryBody = { + 'username': username, + 'id': id, + 'title': title, + 'description': text + }; + if (cacheEnabled) { + //Add Query + Map query = {Queries.colLink: 'add_journal', Queries.colData: jsonEncode(queryBody)}; + + print("adding new query ${query[Queries.colLink]} : ${jsonEncode(queryBody)}"); + + await cacheDb.insert('Queries', query); + + //update Cache + Map data = { + 'id':id, + Journal.colTitle: title, + Journal.colDescription:text + }; + await cacheDb.insert('Journal', data); + await refreshUserData(forceOffline: true); + } else { + try { + http.Response queryResponse = (await http.post(Uri.parse('http://161.97.127.136/task_tracker/add_journal.php'), body: queryBody)); + print("Query executed : Results{${queryResponse.body}"); + if (queryResponse.body.toLowerCase().contains("success")) { + //Success + } + } catch (e) { + print('NC: Error adding journal entry $e}'); + } + //executeQueries(); + } + //Add to server and refresh Cache + await executeQueries(); + + } + static Future editJournal(DateTime oldDay, DateTime day, String title, String text) async { + String oldId = username + DateFormat('yyyy-MM-dd').format(oldDay); + String id = username + DateFormat('yyyy-MM-dd').format(day); + Map queryBody = { + 'username': username, + 'old_id':oldId, + 'id': id, + 'title': title, + 'description': text + }; + if (cacheEnabled) { + //Add Query + Map query = {Queries.colLink: 'edit_journal', Queries.colData: jsonEncode(queryBody)}; + + print("adding new query ${query[Queries.colLink]} : ${jsonEncode(queryBody)}"); + + await cacheDb.insert('Queries', query); + await cacheDb.rawUpdate("UPDATE Journal SET id='$id', ${Journal.colTitle}='${title.toString().replaceAll("'", "''")}', ${Journal.colDescription}='${text.toString().replaceAll("'", "''")}' WHERE id='$oldId'"); + //update Cache + Map data = { + 'id':id, + Journal.colTitle: title, + Journal.colDescription:text + }; + // await cacheDb.insert('Journal', data); + await refreshUserData(forceOffline: true); + } else { + try { + http.Response queryResponse = (await http.post(Uri.parse('http://161.97.127.136/task_tracker/edit_journal.php'), body: queryBody)); + print("Query executed : Results{${queryResponse.body}"); + if (queryResponse.body.toLowerCase().contains("success")) { + //Success + } + } catch (e) { + print('NC: Error adding journal entry $e}'); + } + //executeQueries(); + } + //Add to server and refresh Cache + await executeQueries(); + + } + static Future deleteTask(String name, {bulk = false}) async { Map queryBody = { 'id': username + name, @@ -1372,6 +1547,43 @@ class UserOperations { } } + static Future deleteJournal(String id, {bulk = false}) async { + Map queryBody = { + 'username': username, + 'id': id, + }; + //Add Query + Map query = {Queries.colLink: 'delete_journal', Queries.colData: jsonEncode(queryBody)}; + + print("adding new query ${query[Queries.colLink]} : ${jsonEncode(queryBody)}"); + + if (cacheEnabled) { + await cacheDb.insert('Queries', query); + + //update Cache + String deleteQuery = + "DELETE FROM Journal WHERE id='$id'"; + print("delteQuery : $deleteQuery"); + + await cacheDb.rawDelete(deleteQuery); + await refreshUserData(forceOffline: true); + //Add to server and refresh Cache + } else { + try { + http.Response queryResponse = (await http.post(Uri.parse('http://161.97.127.136/task_tracker/delete_journal.php'), body: queryBody)); + print("Query executed : Results{${queryResponse.body}"); + if (queryResponse.body.toLowerCase().contains("success")) { + //Success + } + } catch (e) { + print('NC: Error deleting journal $e}'); + } + } + if (!bulk) { + await executeQueries(); + } + } + static Future executeQueries() async { if (cacheEnabled) { if (offline) { diff --git a/lib/main.dart b/lib/main.dart index 95b37d9..6a50b37 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -10,6 +10,7 @@ import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:tasktracker/Categories.dart'; +import 'package:tasktracker/Journal.dart'; import 'package:tasktracker/Projects.dart'; import 'package:tasktracker/Todo.dart'; import 'package:tasktracker/Welcome.dart'; @@ -111,7 +112,8 @@ class MyApp extends StatelessWidget { '/Categories': (context) => const Categories(), '/Activities': (context) => const Activities(), '/Settings': (context) => const SettingsPage(), - '/Projects':(context)=> const Projects() + '/Projects':(context)=> const Projects(), + '/Journal': (context)=> const JournalPage() }); }); } @@ -283,7 +285,7 @@ class _MyHomePageState extends State { ongoingActName = ""; } - if(mounted) { + if(this.mounted) { setState(() { }); @@ -1003,7 +1005,7 @@ Drawer navDrawer(BuildContext context, int pageIndex) { ListTile( selected: (pageIndex == 7), title: Text('Projects'), - leading: Icon(Icons.work_outline_sharp, color: Theme.of(context).primaryColor), + leading: FaIcon(FontAwesomeIcons.rocket, color: Theme.of(context).primaryColor), onTap: () { if (pageIndex == 7) { return; @@ -1011,6 +1013,17 @@ Drawer navDrawer(BuildContext context, int pageIndex) { Navigator.of(context).pushReplacementNamed('/Projects'); }, ), + ListTile( + selected: (pageIndex == 8), + title: Text('Journal'), + leading: FaIcon(FontAwesomeIcons.bookJournalWhills, color: Theme.of(context).primaryColor), + onTap: () { + if (pageIndex == 8) { + return; + } + Navigator.of(context).pushReplacementNamed('/Journal'); + }, + ), // ListTile( // selected: (pageIndex == 7), // title: Text('TODO'), @@ -1046,37 +1059,6 @@ Drawer navDrawer(BuildContext context, int pageIndex) { )); } -class MyPlayerBar extends CustomPainter { - MyPlayerBar(this.max, this.value, {this.background = Colors.lightBlue, this.fill = Colors.blue}); - - Color background = Colors.lightBlue; - Color fill = Colors.blue; - final int max; - final int value; - - @override - void paint(Canvas canvas, Size size) { - Paint paint = Paint(); - double cursor = (value * size.width) / max; - Radius cornerRadius = Radius.circular(10.0); - - // Already played half color (your darker orange) - paint.color = background; - - // Painting already played half - canvas.drawRRect(RRect.fromRectAndCorners(Rect.fromLTWH(0.0, 0.0, cursor, size.height), topLeft: cornerRadius, bottomLeft: cornerRadius), paint); - - // Yet to play half color (your lighter orange) - paint.color = fill; - - // Painting the remaining space - canvas.drawRRect(RRect.fromRectAndCorners(Rect.fromLTWH(cursor, 0.0, size.width - cursor, size.height), bottomRight: cornerRadius, topRight: cornerRadius), paint); - } - - @override - bool shouldRepaint(CustomPainter oldDelegate) => true; -} - class CatMapData { CatMapData(this.name, this.time, this.color); final String name; diff --git a/pubspec.lock b/pubspec.lock index 2145f43..69e2f7a 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -450,6 +450,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.27.3" + scrollable_positioned_list: + dependency: "direct main" + description: + name: scrollable_positioned_list + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.3" shared_preferences: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index fd460cb..951b3b3 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -30,6 +30,7 @@ dependencies: flutter: sdk: flutter + scrollable_positioned_list: ^0.2.3 sticky_headers: ^0.2.0 flutter_switch: ^0.3.2 sqflite_common_ffi: ^2.1.0+2